《剑指offer》-数组中出现次数超过一半的数字

/*
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
*/

class Solution {
public:
    /*
    最开始的想法:排序后,假如存在元素满足题目条件,那么中间位置的元素就是这样的元素,那么双向增长,判断增长停滞点之间的长度
    缺点是复杂度过高
    int MoreThanHalfNum_Solution(vector<int> numbers) {
    	sort(numbers.begin(), numbers.end());
        if(numbers.size()==0){
            return 0;
        }
        if(numbers.size()==1){
            return numbers[0];
        }
        int mid = (numbers.size()-1)/2;
        int low=mid, high=mid+1;
        while(low>=0 && high<=numbers.size()-1){
            if(numbers[low]==numbers[mid]){
                low--;
            }
            if(numbers[high]==numbers[mid]){
                high++;
            }
        }
        int len = high - low + 1;
        if(len>numbers.size()/2) return numbers[mid];
        return 0;
    }*/
    

        // 讨论帖中的做法,个人理解为:假如有某个数字出现次数超过一半,那么它们每个元素有一口气,我累计收集这些气(遍历):
        // 遇到这个元素,气+1;遇到其他元素,气-1;如果气等于0,则更新气味为新元素的气;
        // 最后验证一下这个气是否为所求:因为留下来的气,对应元素出现次数可以少于一半。
	int MoreThanHalfNum_Solution(vector<int> numbers){
		int n = numbers.size();
		if (n == 0) return 0;
		
		int num = numbers[0], count = 1;
		for (int i = 1; i < n; i++){
			if (numbers[i] == num) {
				count++;
			}
			else{
				count--;
			}
			if (count == 0){
				num = numbers[i];
				count = 1;
			}
		}

		//verification
		count = 0;
		for (int i = 0; i < n; i++){
			if (numbers[i] == num){
				count++;
			}
		}
		if (count * 2 > n){
			return num;
		}
		return 0;
	}
};
原文地址:https://www.cnblogs.com/zjutzz/p/6657968.html