题目
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路一
基于partition,挑一个数字,把数组分成两部分,左边都比它小,右边都比它大。
因为有一个数字出现的次数超过长度的一半
因此当选中的数字的index = n/2,这个数字就是中位数
然后再检查它次数是否超过一半即可,时间复杂度为O(n)
class Solution { public: int MoreThanHalfNum_Solution(vector<int> numbers) { if (numbers.size() == 0) return 0; int length = numbers.size(); int mid = length >> 1, start = 0, end = length - 1; int index = Partition(numbers, start, end); while (index != mid){ if (index > mid){ end = index - 1; index = Partition(numbers, start, end); } else{ start = index + 1; index = Partition(numbers, start, end); } } if (!CheckMoreThanHalf(numbers, numbers[index])) return 0; return numbers[index]; } int Partition(vector<int>& input, int begin, int end) { int low = begin, high = end; int pivot = input[low]; while(low < high) { while( low < high && pivot<=input[high]) high--; input[low] = input[high]; while(low < high && pivot >= input[low]) low++; input[high] = input[low]; } input[low] = pivot; return low; } bool CheckMoreThanHalf(vector<int> numbers, int temp){ int times = 0; int len = numbers.size(); for (int i = 0; i < len; i++){ if (numbers[i] == temp) times++; } if (2 * times > len ) return true; else return false; } };
思路二
在遍历数组时,当遍历下一个数字和当前保存数字相同,则加1,不同则减1。
若次数为0的话,则需要保存下一个数字,同时次数设为1
要找的数字肯定是最后一个把次数设为1时对应的数字。
class Solution { public: int MoreThanHalfNum_Solution(vector<int> numbers){ if (!numbers.size()) return 0; int length = numbers.size(); int result = 0, count = 1, temp = numbers[0]; for (int i = 1; i < length; i++){ if (numbers[i] == temp) count++; else count--; if (count == 0){ count = 1; temp = numbers[i]; } } if (CheckMoreThanHalf(numbers, temp)) return temp; else return 0; } bool CheckMoreThanHalf(vector<int> numbers, int temp){ int times = 0; int len = numbers.size(); for (int i = 0; i < len; i++){ if (numbers[i] == temp) times++; if (2 * times > len) return true; else return false; } } };
原文地址:https://www.cnblogs.com/shiganquan/p/9343370.html
时间: 2024-10-30 20:56:35