• 数组中出现次数超过数组长度一半的值 分类: C/C++ 2015-07-09 15:38 142人阅读 评论(0) 收藏


    题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为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;
    }




  • 相关阅读:
    javascript
    自己动手、丰衣足食!<菜单导航栏------不简单>
    补---div渐变色条
    自己动手、丰衣足食!<箭头 → ← → ← ---2>
    自己动手、丰衣足食!<箭头 → ← → ← ---1>
    6.19 抽象类
    6.19 多态
    6.19 提纲
    6.18 继承
    6.18 (继承+(四类访问修饰符+程序集+静态方法))提纲
  • 原文地址:https://www.cnblogs.com/zclzqbx/p/4687065.html
Copyright © 2020-2023  润新知