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

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

最坏情况时间复杂度为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. Deployer 的安装与配置

    Deployer 是一个 composer 包,你可以选择以 phar 包的形式,或者以 composer 全局安装来使用它,这里只讲后者,毕竟这是推荐大家使用的方式,升级也会方便很多: $ comp ...

  2. Linux常用系统文件目录结构

    Linux常用系统文件目录结构 bin:全称binary,含义是二进制.该目录中存储的都是一些二进制文件,文件都是可以被运行的. dev:该目录主要存放的是外接设备,例如硬盘.其他的光盘等.在其中的外 ...

  3. F2. Same Sum Blocks (Hard) 解析(思維、前綴和、貪心)

    Codeforce 1141 F2. Same Sum Blocks (Hard) 解析(思維.前綴和.貪心) 今天我們來看看CF1141F2(Hard) 題目連結 題目 給你一個數列\(a\),要你 ...

  4. IntelliJ IDEA 使用指南:集成GIT客户端

    一.安装GIT客户端 首先需要在本地安装好GIT的客户端. GIT客户端官网下载地址:https://www.git-scm.com/download/ 安装说明 Linux系统安装 使用yum指令 ...

  5. 【CF1443F】Identify the Operations 题解

    原题链接 题意简介 建议去原题看.这题意我表达不清楚. 大概就是给你一个 n 的排列,现在要求你进行 m 次操作. 每次操作,你会在现有的排列中删去一个数,然后选择其左边或右边的一个与之相邻的数加入 ...

  6. linux修改ssh远程端口22

    建议先查看redhat的release版本,CentOS 7的启动服务不同: # more /etc/redhat-release 正文: 如题: 在此前,建议先查看redhat的release版本, ...

  7. 题解 AT3877 【[ARC089C] GraphXY】

    参考的博客 在[有趣的思维题]里看到了这道题. 题意: 给出一个\(A\times B\)的矩阵,其中第i行第j列元素为\(d_{i,j}\),试构造一个有向图,满足: 有向图点数\(\le 300\ ...

  8. Redis系列文章-数据结构篇

    Redis系列文章 前言: 工作原因,在学习mybatis知识后,2个月没有补充新的知识了,最近拿起书本开始学习.打算写下这个Redis系列的文章. 目录结构如下: Redis内置数据结构 Redis ...

  9. Shell脚本常用命令整理

    该笔记主要整理了一些常见的脚本操作命令,大致如下(持续补充中): 1. while.for循环 1. while.for循环 #!/bin/bash # while循环 v_start_date=${ ...

  10. Martini初步

    部分内容来自http://jerkwin.github.io/9999/08/01/Martini%E7%B2%97%E7%B2%92%E5%8C%96%E5%8A%9B%E5%9C%BA%E4%BD ...