算法:O(n)时间内在数组中找到第k个小的数

无序数组找到最小的k个 O(N)解法 快速排序原理方法和BFPRT方法 最简便的方法是循环K次,依次找出最小的,第2小的,第K小的值,时间复杂度O(N*K),这种方法使用于K比较小的时候,如个位,如果N据量很大,K也较大,不适用。因为K大于N时,时间复杂度变成O(N^2)。 第二种是堆排序,建立一个大根堆,时间复杂度是O(NlogK),此方法博客中有写到,详见堆排序。 一、用快速排序,随机取枢轴量可以做到平均时间复杂度O(N),但是值选的不好会退化到O(N^2... 阅读详情

从一个长度为n的无序数组中,找到第k小的那个数,被称为k-select问题。我们经常见到的问题:找到中位数,找到第二个大的数,都是这个问题的特例。

算法的复杂度是O(20n),当选择为5个数为一个小集合时。

OJ风格的完整代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>

#define Q 5
#define LOCAL

int A[1001];
int n;
int k;


int cmp(const void *a, const void *b) {
	return *(int *)a - *(int *)b;
}

int trivivalSelect(int *A, int n, int k) {
	int temp[1001];
	memset(temp, 0, sizeof(int)*1001);
	memmove(temp, A, sizeof(int)*n);
	qsort(temp, n, sizeof(int), cmp);
	printf("trivivalSelect: %d\n", temp[k]);
	return temp[k];
}


int kselect(int* A, int n, int k) {
	if (n < Q) {
		return trivivalSelect(A, n, k);
	}
	int mid[1001];
	int temp[1001];
	memset(mid, 0, sizeof(int)*1001);


	
	int i = 0;
	int c = 0;
	while (i < n) {
		int count = (n - i < Q ? n - i : Q);
		memset(temp, 0, sizeof(int)*1001);
		memmove(temp, A + i, sizeof(int)*count);
		qsort(temp, count, sizeof(int), cmp);
		mi
线性时间选择—寻找第k小的(分治算法 问题描述: 找出一个数组中第K小的元素,时间复杂度为O(n)。 思想 首先,找出数组元素的中位的中位,然后利用Partition函对整个数组进行划分,以数组中中位的中位为基准将数组划分为两部分——左边部分的所有都小于基准,右边部分都大于基准,并返回基准的下标值。 最后,如果要找到第k小个,就将k的大小与数组左半边元素的个(包括基准)进行比较,如果k小于j,则对左边部分进行递归,找第k小个;若k大于j,则对右边部分进行递归,找第k减去j个小。 代码如下: #include "stdafx 阅读详情

相关推荐

BFPRT算法时间复杂度O(n)第k小的字(分治算法+快排)

去年写了一篇《分治算法 第k小元素 O(n)》的文章。介绍了一种对快排进行改进的算法,可以在时间复杂度O(n)的情况下,找到第k小的字。那时候,我还不知道这个算法叫BFPRT算法——现在知道了,还知道它又被称为中位的中位算法,它的最坏时间复杂度为O(n),它的思想是修改快速选择算法的主元选取方法,提高算法在最坏情况下的时间复杂度。而且,我还发现了STL中有一个类似的函——std::nth_element (位于头文件`&amp;amp;amp;amp;amp;lt;algorithm&am

机器学习 7387

第k小的(快速排序)

算法思想: 时间复杂度:O(n) 在快速排序的过程中,可以分为两段, [l,j][l,j][l,j]这段都是小于等于随机值的 [j+1,r][j + 1,r][j+1,r]这段都是大于等于随机值的 左边这段有 j−l+1j - l + 1j−l+1 个(记作 slslsl) 也就是说第 111 ~ slslsl (包括sl)小的字都在左边 第 sl+1sl + 1sl+1 ~ nnn 小的字都在右边 如果 kkk 是在左边,那直接在左边即可 如果 kkk 是在右边,那么直接在右边即可,此时第k小变

Botton's blog 1188

uni-app刮奖

uni-app的刮奖效果,要注意的点: 1.小程序的canvas层级问题(可用cover-view规避) 2.不能操作dom 以下是uni-app刮奖效果的代码: <template> <!-- 刮奖 --> <view v-else class="scratch"> <view class="box"> &lt...

qq_40101922的博客 4293

已知数组A[1...n] ,确定第K小元素 算法时间复杂度O(n)

可以用快速排序的Partition思想。

sh_c1991的专栏 1736

快速选择算法时间复杂度为什么是O(n)

一、引言 今天学了一个快速选择算法,这个算法跟快排差不多,只不过专门用来在选择数组中第k大/小的时,可以免去将整个数组排序后选择第k个。将整个数组排序再选择第k个时间复杂度是O(nlog(n)),快速选择算法将平均时间复杂度优化到O(n),但最坏的情况还是O(n^2)。一开始很纠结这个O(n)是怎么来的,后来看了一下别人的分析,得到了答案。 二、分析 这里大概分析一下O(n)怎么来的...

W__M__W的博客 7663

如何在o(n)内查找第k小的元素

o(n)时间复杂度内无序数组中的第k小元素。比如,4,2,5,11,6这样一组据,第3小的元素就是6。

2202_75326422的博客 448

寻找数组中第K大的时间复杂度O(N)

给定一个数组A,要找到数组A中第K大的字。对于这个问题,解决方案有不少,此处我只给出三种: 方法1:   对数组A进行排序,然后遍历一遍就可以找到第K大的字。该方法的时间复杂度为O(N*logN) 方法2:   利用简单选择排序法的思想,每次通过比较选出最大的字来,比较上K次就能找出第K大的字来。该方法的时间复杂度为O(N*K),最坏情况下为O(N^2)。 方法3:     这种方法是本文谈论的重点,可以利用快排的思想,首先快排每次执行都能确定一个元素的最终的位置,如果这个位置是n-k

salmonwilliam的博客 1万+

在一个数组找到第k小的(线性时间选择)

在一个数组找到第k小的(线性时间选择) 在这一部分,我们讨论的题目为元素选择问题。这类题目的一般问法为:给定线性序集中n个元素和一个整k,1 <= K <= n,要找出这n个元素中第k小的元素,如(1,4,3,2,5)中第一小的元素就是1,第5小的元素就是5,第2小的元素就是2。 在某些特殊情况下,很容易设计出解选择问题的线性时间算法。如:当要选择最大元素或最小元素时,显然...

IT_Quanwudi的博客 7051

O(n)级选排名第k位(附上算法复杂度分析)

算法简述 如果想要拿到第k位,一般说复杂度都比较高。例如,用快排等方式,要用了O(nlogn)水平的时间复杂度。就算是用快排改进,每次在快排的基础上,只排剩下的一部分,在平均水平上,也会变成了O(nlogn)。 原因是,如果是第一个本来就比较小,这样在快排的基础上,第一步根本都没有能够发生多少的移动。那么,这样子算法复杂度降低会特别慢的。 一个比较好的方式就是,如果能保证每次都能有很大一个比例(...

gc.collect() 700

静态区间第K小--O(N)算法

快速排序第k小

Azure_stars的博客 332

线性时间内从一个数组中找出第K个最小的元素

/* 思路:用调优的快速排序,首先随机选择一个pivot对数组进行划分,左边小于pivot,右边大于等于pivot, 所以我们计算左边小于pivot(加上pivot)的个count总共有多少, 如果等于k,正是我们所要的,返回x[k]; 如果大于k,说明第k小的在左边,那就在左边进行我们的递归; 否则,在右边,那么说明右边的第k-count小的就是我们所要的,在右边进行我们的递归。 这样的平

奋斗、 1907

找出数组中最小的k个

LeetCode https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/ 面试题40. 最小的k个 解法一:O(nlogn) 快速排序,时间复杂度为nlogn,然后前k个元素就是最小的k个 class Solution { public int[] getLeastNumbers(int[] arr, int k) {...

Mason97的博客 3423

选择问题算法

对于给定的n 个元素的数组A (1 : n ),要从中找出第k小的元素。如果划分元素v测定在A(j)的位置上,则有j-1个元素小于或等于A(j),且有n-j个元素大于或等于A(j)。因此,若k,则第k小元素在A(1:j-1)中;若k=j,则A(j)就是第k小元素;若k>j,则第k小元素是A(j+1:n)中第(k-j)小元素。所导出的算法如果成SELECT。此过程把第k小元素放在A(k),并划分

Stephan14的专栏 1522

找出无序数组中第k小的元素

思路 要找到第k小的元素,可以先将数组排序,再返回第k[-1]个元素即可,这里排序选择效率较高的归并排序 具体实现: /* author: QGQ description: 对于给定的n个元素的数组a[1..n],要从中找出第k小的元素。 datetime: 2021年3月28日 13点37分 */ #include <stdio.h> #include <stdlib.h> int length; int *B;

闻风听雨的博客 1883

在O(n)时间内查找数组内第k小的

前一阵子做作业,看到了这个,要在 O(n) 时间内查找前 k 小的 k 个,给出的提示是,先在 O(n) 时间内查找到第 k 小的.由此想到,此前一直用的 sort 函,排完序后找下标为 k-1 的那个,却从来没有考虑过具体的实现.结合前一阵子学习的快速排序算法,大致对此有了新的认识.首先给出一个函,可以出轴值在(排完序的)数组中的位置. 这里是假设区间的第一个为轴值.int Pa

pku_Coder的博客 2820

【相当困难】找到无序数组中最小的k个-Java:O(N)的解法

package live.every.day.ProgrammingDesign.CodingInterviewGuide.ArrayAndMatrix; import java.util.Arrays; /** * 找到无序数组中最小的k个 * * 【题目】 * 给定一个无序的整型数组arr,找到其中最小的k个。 * * 【要】 * 如果数组arr的长度为N,排序之后自然可以得到最小的k个,此时时间复杂度与排序的时间复杂度相同,均为O(NlogN)。本题要 * 读者实现时间

了解➔熟悉➔掌握➔精通 635

k-选取问题之快速选取策略quickSelection

1. 问题描述: k-选取问题:从一组无序数组中,找出第k大的元素。 2. 思路分析: 通常想到的是先排序,然后直接取出秩为k的元素,即为所解。但是根据比较式算法的结论:该算法最坏情况下需要O(nlogn)时间复杂度。对于一个容量较大的数组来说,复杂度太高。 这里介绍一种基于减而治之、逐渐逼近的策略,即利用二分思想来解决这个问题。它可以在最好或...

aishuirenjia的博客 1063

查找第k小的元素(O(n)递归解法)

今天分享一个小技巧,虽然是小技巧但是还是很有价值的,曾经是微软的面试题。题目是这样的,一个无序的数组让你找出第k小的元素,我当时看到这道题的时候也像很多人一样都是按普通的思维,先排序在去第K个,但是当数组非常大的时候,效率不高,那有没有简单的方法了,其实我们早就学过,只是我们不善于思考和变通。很多人刚开始非常热衷于各种排序算法只是了解却没深究,这个题目的复杂度是O(n),原理就是快速排序里面的划分...

weixin_34303897的博客 564

在无序数组第K小的

bfprt算法的讲解以及使用bfprt算法和改写快排两种方法解决“无序数组第K小的”问题

明朗晨光的专栏 1104

ansys非线性分析中接触类型

不分离(No Separation)‌:法向始终保持接触不分离,切向允许自由滑动,属于线性接触,适合需要法向约束、允许微小切向位移的场景,比如过盈配合的简化模拟。有摩擦(Frictional)‌:法向允许分离,切向根据用户设置的摩擦系计算摩擦力,是工程中最符合实际机械接触的类型,绝大多装配体分析都选择该类型。无摩擦(Frictionless)‌:法向允许接触面分离,切向无摩擦、允许自由滑动,适合模拟理想润滑的光滑接触面,图中当前选择的就是该类型。非线性接触(需要多次迭代,属于真正的非线性接触行为)‌。

qq_15963745的博客 40

vlc SDK 包

VLC SDK包,2.2.6版本,包含32位 和 64位两个版本,视频开发必备,包含lib库,实测可用

上一篇: cprintf函数调用到屏幕(cga)输出流程分析
下一篇: 本科生找实习太TM难了--我的2018春季实习应聘记录(截止到2018.5.18)
old_memory
博客等级 码龄10年 5粉丝 8原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值