分治思想求解的问题,但是比较特殊,只有分解问题和求解小问题,不需要合并

每次也只需要经过判断,分解一半,所以比其他分解两边的效率高

最坏情况时间复杂度为O(n^2),期望时间复杂度为O(n)

找基准值时候可以考虑随机选择

#include<iostream>
#include<vector>
#include<algorithm>
#include<random>
#include<ctime>
using namespace std;
int select(vector<int>& data, int left, int right, int k); int main()
{
//次序选择问题:求数组中第k小的元素
// 思想:分而治之
// 将问题分解partition
// 如果要找的第k个元素正好是基准值,那正好,也就是最好情况了,时间复杂度为O(n),因为只进行了一次partition
//如果要找的第k个元素在基准值左侧,也就是左子数组里,那么在子数组里,还是找第k小元素
//如果要找的第k个元素在基准值右侧,也就是右子数组里,那么在右子数组里,找的是第k-(q-p+1)个元素 int k = 1;
vector<int> data = { 7,5,6,4,3,1,9 };
//获取序列元素个数
int length = data.size();
int left = 0;
int right = 6;
int result;//用来保存第k小元素的值
result = select(data, left, right, k);
cout << result << endl;
}
int select(vector<int>& data, int left, int right, int k)
{
if (left == right)
return data.at(left);//递归结束的条件 //这部分是partition,也可以单独写成一个函数调用
int key = data.at(right);
/*这里有一种优化的方法,就是这个中轴数随机的找,然后交换到末尾,再往下执行*/
/*
default_random_engine e(time(0)); //时间引擎
uniform_int_distribution<signed> u(left, right);
int key = u(e);
int tem = data.at(key);
data.at(key) = data.at(right);
data.at(right) = tem;
int ave = data.at(right);
*/
int i = left - 1;
for (int j = left; j < right; j++)
{
if (data.at(j) <= key)
{
i++;
int temp = data.at(j);
data.at(j) = data.at(i);
data.at(i) = temp;
}
}
//将基准值放在合适的位置
i++;
int temp = data.at(i);
data.at(i) = key;
data.at(right) = temp;
//此时的i就是基准值的位置
//以上是partition部分,可以单独写成函数调用 //当前第cur小的元素,这里很重要,一定要这么写
int cur = i - left + 1;
if (k == cur)//如果基准值正好是第k小元素
return data.at(i);
else if (k < cur)//要找的第k小元素出现在左边
{
return select(data, left, i - 1, k);
}
else
{
return select(data, i + 1, right, k - cur);//如果出现在右边,原始的第k小元素在右边子数组中就是第k-cur小元素,这里很重要
}
}

【C++】数组中的第k个最小元素的更多相关文章

  1. 代码题(3)— 最小的k个数、数组中的第K个最大元素、前K个高频元素

    1.题目:输入n个整数,找出其中最小的K个数. 例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 快排思路(掌握): class Solution { public ...

  2. 寻找数组中的第K大的元素,多种解法以及分析

    遇到了一个很简单而有意思的问题,可以看出不同的算法策略对这个问题求解的优化过程.问题:寻找数组中的第K大的元素. 最简单的想法是直接进行排序,算法复杂度是O(N*logN).这么做很明显比较低效率,因 ...

  3. LeetCode:数组中的第K个最大元素【215】

    LeetCode:数组中的第K个最大元素[215] 题目描述 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: ...

  4. Leetcode题目215.数组中的第K个最大元素(中等)

    题目描述: 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 ...

  5. Java实现 LeetCode 215. 数组中的第K个最大元素

    215. 数组中的第K个最大元素 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6 ...

  6. 215. 数组中的第K个最大元素 + 快速排序 + 大根堆

    215. 数组中的第K个最大元素 LeetCode-215 另一道类似的第k大元素问题:https://www.cnblogs.com/GarrettWale/p/14386862.html 题目详情 ...

  7. LeetCode215. 数组中的第K个最大元素

    215. 数组中的第K个最大元素 问题描述 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 示例 1: 输入: [3 ...

  8. LeetCode 215——数组中的第 K 个最大元素

    1. 题目 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 ...

  9. Leetcode 215.数组中的第k个最大元素

    数组中的第k个最大元素 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 ...

随机推荐

  1. CentOS7 安装telnet-0.17-64.el7.x86_64

    1.安装客服端,服务端,xinetd yum -y install telnet telnet-server xinetd 以上要想完成telnet安装,telnet服务端和xinetd必须安装,至于 ...

  2. vue-cli3使用jq

    第一步安装 npm install jquery --save 第二部配置vue.config.js, 没有这个文件就创建 主要是框框出来的那些: 忽略我配置的另一个uglifyjs-webpack- ...

  3. OpenCascade拓扑对象之:Face的方向、参数域和曲面间的关系

    @font-face { font-family: "Times New Roman" } @font-face { font-family: "宋体" } @ ...

  4. 深入探究ASP.NET Core Startup初始化

    前言 Startup类相信大家都比较熟悉,在我们使用ASP.NET Core开发过程中经常用到的类,我们通常使用它进行IOC服务注册,配置中间件信息等.虽然它不是必须的,但是将这些操作统一在Start ...

  5. EBAZ4205学习资源整理

    EBAZ4205是一块矿机的控制板,芯片是ZYNQ7010,某鱼上应该不超过30元就能买一块,垃圾佬狂喜 经过不复杂的操作就能进行正常开发,由于货量比较大现在已经有很多大佬写了很多很多好的资料,这里我 ...

  6. 深入理解golang:内存分配原理

    一.Linux系统内存 在说明golang内存分配之前,先了解下Linux系统内存相关的基础知识,有助于理解golang内存分配原理. 1.1 虚拟内存技术 在早期内存管理中,如果程序太大,超过了空闲 ...

  7. 聊一聊C#基本类型

    C#基本类型 闲来无事,重新温习了下C#基本类型.以下讲的基本类型主要是包括基本的值类型类型和string.struct和class不包含其中. C#基本类型------值类型: bool,byte, ...

  8. 获取List集合对象中某一列属性值

    例:获取disposeList集合中CorpusMarkPage对象中的responseId属性,生成新的List集合 List<String> responseIdList = disp ...

  9. day89:luffy:使用Celery完成我的订单超时取消&Polyv视频加密播放

    目录 1.我的订单超时取消 2.PoliV视频播放 1.我的订单超时取消 使用Celery完成超时取消功能 mycelery/order/tasks.py from mycelery.main imp ...

  10. 痞子衡嵌入式:超级下载算法(RT-UFL)开发笔记(2) - 识别当前i.MXRT型号

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是超级下载算法开发笔记(2)之识别当前i.MXRT型号. 文接上篇 <超级下载算法(RT-UFL)开发笔记(1) - 执行在不同CM ...