数组中出现次数超过数组长度一半的值
Posted wzjhoutai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数组中出现次数超过数组长度一半的值相关的知识,希望对你有一定的参考价值。
题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。比如输入一个长度为18的数组{1,0,2,6,1,0,1,1,5,2,1,1,1,3,1,1,5,1}, 因为数组中数字1出现的次数超过数组的长度的一半,因此输出1。
1)最直接的办法是先把数组排序,那么超过一半的元素一定是数组最中间的元素。
2)再深入思考一下就会想到高速排序过程,利用partion找出index==middle时,index相应的值,而不必全然排序。
3)另外一种办法比較抽象,设一个变量保存当前值,设一个次数,当前值与下一个值进行比較,假设相等,次数加一。假设不相等。次数减一,假设次数减到0了还是不相等。就把当前值替换掉。
这里仅仅展示了2)、3)的源代码,没有数据合理性校验。
#include<iostream> #include<vector> using namespace std; int partion(vector<int>& vec,int low,int high) {//高速排序的基础 int key = vec[high]; int fast = low; int slow = low; while (fast < high) { if (vec[fast] <= key) { if (fast == slow) slow++; } else { if (fast != slow) { int tmp = vec[slow]; vec[slow] = vec[fast]; vec[fast] = tmp; slow++; } } fast++; } int tmp = vec[slow]; vec[slow] = vec[high]; vec[high] = tmp; return slow; } int find_half1(vector<int> vec) { int length=vec.size(); if (length == 0) return 0; int start = 0; int end = length - 1; int middle = length >> 1; int index = partion(vec, start, end); while (index != middle) {//中位值肯定是出现次数超过一半的数 if (index > middle) { end = index - 1; index = partion(vec, start, end); } else { start = index + 1; index = partion(vec, start, end); } } cout << "index:" << index << endl; return vec[index]; } int find_half2(vector<int> vec) {//设置key和index。假设出现等于key的值,index++,否则index--; //假设index==0,则更新key的值,由于目标值出现次数超过一半,所以,index必定大于0 int key=vec[0]; int index = 0; for (int i = 0; i < vec.size(); ++i) { if (vec[i] == key) { index++; } else { if (index == 0) { key = vec[i]; index++; } else { index--; } } } return key; } int main() { int a[18] = {1,0,2,6,1,0,1,1,5,2,1,1,1,3,1,1,5,1}; vector<int> vec(a, a + 18);//这样的容器初始化方式非常实用 for (int i = 0; i < vec.size(); ++i) { cout << vec[i] << " "; } cout << endl << find_half1(vec) << endl; return 0; }
以上是关于数组中出现次数超过数组长度一半的值的主要内容,如果未能解决你的问题,请参考以下文章