[剑指Offer]39-数组中出现次数超过一半的数字(快排延申,找第k大数同理)
题目链接
题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
解题思路
- 思路一:
排序再计数,时间复杂度O(nlogn)。 - 思路二:
思路:利用快排的partion函数。
算法描述:记数组长度为n,数组第n/2大的数即中位数即是要找的数。利用快排思想,每一轮partition后,定位一个数(位置也表示第几小),将该数的位置与中位比较,若该数的位置大于中位,则应partion该数左侧的这些比该数小的数。反之partion右侧。直到partion的这个数位置是中位。
时间复杂度O(n),但会改变输入。 - 思路三:
思路:由题,所求数比其他所有数出现次数还要多。
算法描述:遍历数组,记两个变量,一个是临时元素变量,一个是次数,当便利到的的元素与临时元素变量相同则次数++,相异则次数--;若次数已为0,则临时元素变量换为下一个元素,次数设为1;这样最终的临时元素所存元素即为所求值。
时间复杂度O(n)
关于特例:若输入数组中没有出现次数超过一半的数,则返回0.对于思路二的解法,这个要在找到第n/2大数后判断一下。
相关知识
我认为,关于快排,精髓在于partion函数:即每次定位一个数,即是最终排序的位置,且该数左侧的数都比它小,右侧的数都比它大。
思路二代码 O(n)
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if (numbers.empty()) {
return 0;
}
int index = partition(numbers, 0, numbers.size() - 1);
int mid = numbers.size() >> 1;
while (index != mid) {
if (index > mid) {
index = partition(numbers, 0, index - 1);
}
else if (index < mid) {
index = partition(numbers, index + 1, numbers.size());
}
}
if (!moreThanHalfCheck(numbers, numbers[index])) {
return 0;
}
else {
return numbers[index];
}
}
private:
int partition(vector<int>& num, int start, int end) {
if (num.empty() || start > end || start < 0) {
throw "invaild!";
}
int index = randomInRange(start, end);
swap(num[start], num[index]);
int l = start;
int r = end;
int tempElm = num[l];
while (l<r)
{
while (num[r] >= tempElm && l < r) {
--r;
}
if (l != r) {
num[l] = num[r];
++l;
}
while (num[l] <= tempElm && l < r) {
++l;
}
if (l != r) {
num[r] = num[l];
--r;
}
}
num[l] = tempElm;
return l;
}
int randomInRange(int start, int end) {
if (start > end) {
throw"invaild!";
}
srand((unsigned)time(0));
int index = start + rand() % (end - start + 1);
return index;
}
void swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
bool moreThanHalfCheck(vector<int> numbers, int number) {
int numberCnt = 0;
for (int i = 0;i < numbers.size();++i) {
if (numbers[i] == number) {
++numberCnt;
}
}
if (numberCnt > numbers.size() / 2) {
return true;
}
else {
return false;
}
}
};
思路三代码
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if (numbers.empty()) {
return 0;
}
int num;
int numCnt = 0;
for (int i = 0;i < numbers.size();++i) {
if (numCnt == 0) {
num = numbers[i];
++numCnt;
}
else {
if (numbers[i] == num) {
++numCnt;
}
else {
--numCnt;
}
}
}
if (!moreThanHalfCheck(numbers,num)) {
return 0;
}
else {
return num;
}
}
private:
bool moreThanHalfCheck(vector<int> numbers, int number) {
int numberCnt = 0;
for (int i = 0;i < numbers.size();++i) {
if (numbers[i] == number) {
++numberCnt;
}
}
if (numberCnt > numbers.size() / 2) {
return true;
}
else {
return false;
}
}
};
[剑指Offer]39-数组中出现次数超过一半的数字(快排延申,找第k大数同理)的更多相关文章
- 剑指 Offer 39. 数组中出现次数超过一半的数字 + 摩尔投票法
剑指 Offer 39. 数组中出现次数超过一半的数字 Offer_39 题目描述 方法一:使用map存储数字出现的次数 public class Offer_39 { public int majo ...
- 剑指 Offer 39. 数组中出现次数超过一半的数字
剑指 Offer 39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 你可以假设数组是非空的,并且给定的数组总是存在多数元素. 示例 1: 输入: [ ...
- 力扣 - 剑指 Offer 39. 数组中出现次数超过一半的数字
题目 剑指 Offer 39. 数组中出现次数超过一半的数字 思路1(排序) 因为题目说一定会存在超过数组长度一半的一个数字,所以我们将数组排序后,位于length/2位置的一定是众数 代码 clas ...
- 【Java】 剑指offer(39) 数组中出现次数超过一半的数字
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如 ...
- 每日一题 - 剑指 Offer 39. 数组中出现次数超过一半的数字
题目信息 时间: 2019-06-29 题目链接:Leetcode tag: 数组 哈希表 难易程度:简单 题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 假设数组是非空的 ...
- 剑指Offer:数组中出现次数超过一半的数字【39】
剑指Offer:数组中出现次数超过一半的数字[39] 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如,输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于这 ...
- 【剑指Offer】数组中出现次数超过一半的数字 解题报告(Python)
[剑指Offer]数组中出现次数超过一半的数字 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-inter ...
- Go语言实现:【剑指offer】数组中出现次数超过一半的数字
该题目来源于牛客网<剑指offer>专题. 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组 ...
- 剑指OFFER之数组中出现次数超过一半的数字(九度OJ1370)
题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2 ...
- 剑指Offer 28. 数组中出现次数超过一半的数字 (数组)
题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...
随机推荐
- C# 申请非托管内存
方式一:使用 stackalloc 关键字 int* block = stackalloc int[100]; 注:此关键字仅在局部变量初始值设定项中有效. 以下代码导致编译器错误. int* blo ...
- JSP页面java代码报错:Purgoods cannot be resolved to a type
错误提示 : Purgoods cannot be resolved to a type Purgoods不能解析为一个类型 原因 : 缺少引入Purgoods类 页面中引入java类,执行java代 ...
- RESTFUL 设计风格
RESTFUL 规范总结: Rest是web服务的一种架构风格;使用HTTP,URI,XML,JSON,HTML等广泛流行的标准和协议;轻量级,跨平台,跨语言的架构设计;它是一种设计风格,不是一种标 ...
- Future Clalback使用案例
目前知道可以实现线程按照顺序的java原生方法有 join(),CountDownLatch,Executors.newSingleThreadExecutor(),FutureTask.. Futu ...
- UNITY 多个子MESH与贴图的对应关系
多个贴图时,与子MESH一一对应,如果多了 ...还待研究如何对应
- Graylog日志管理系统---搜索查询方法使用简介
Elasticsearch 是一个基于 Lucene 构建的开源.分布式.提供 RESTful 接口的全文搜索引擎 一.Search页面的各位置功能介绍: 1.日志搜索的时间范围 为了使用方便,预设有 ...
- php运行代码流程和性能优化方法
---恢复内容开始--- php文件->扫描->zd引擎去理解->opcodes->执行->输出 例子,用white随机循环20000数据进行性能测试,分别对比isset ...
- 【372】Kaggle 相关经验
参考:机器学习系列(3)_逻辑回归应用之Kaggle泰坦尼克之灾 参考:Kaggle泰坦尼克特征工程和模型融合 『解决一个问题的方法和思路不止一种』『没有所谓的机器学习算法优劣,也没有绝对高性能的机器 ...
- plsql和tsql常用函数比对
http://www.jb51.net/list/list_154_1.htm 数学函数 1.绝对值 S:select abs(-1) value O:select abs(-1) value fro ...
- servlet(2)response常用方法
详细的response 学习笔记是: 输出到前台的的方法 1:使用OutputStream流向客户端浏览器输出中文数据 2:使用PrintWriter流向客户端浏览器输出中文数据 3:使用Output ...