Leetcode 169 多数元素
多数元素(Majority Element)
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋
的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入:[3,2,3]
输出:3
示例 2:
输入:[2,2,1,1,1,2,2]
输出:2
进阶:
- 尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。
int majorityElement(int* nums, int numsSize){
while (true){
int i = rand() % numsSize;
int count = 0;
for(int j =0 ; j<numsSize; j++){
if(nums[j] == nums[i]){
count++;
}
}
if (count > numsSize/2){
return nums[i];
}
}
return 0;
}
因为有一半以上的概率获得的数字是占一半以上的元素,效率难以评估
int cmp(const void* a, const void* b){
return *(int *)a- *(int *)b;
}
int majorityElement(int* nums, int numsSize){
qsort(nums, numsSize, sizeof(int), cmp);
return nums[numsSize/2];
}
看到这个题目,应该可以很自然的想到哈希表,但是C本身不自带,手动实现Hash表
struct Entry {
int num;
int count;
};
void addOne(struct Entry *countMap, int num, int hashTableSize) {
int hash = (num % hashTableSize + hashTableSize) % hashTableSize;
while (true) {
if (countMap[hash].count == 0){
countMap[hash].num = num;
countMap[hash].count++;
return;
}
if (countMap[hash].num == num){
countMap[hash].count++;
return;
}
hash = (hash + 1) % hashTableSize;
}
}
int majorityElement(int* nums, int numsSize){
int hashTableSize = numsSize * 2;
struct Entry countMap[hashTableSize];
for (int i =0; i<hashTableSize; i++){
countMap[i].count = 0;
}
for (int i = 0; i < numsSize; ++i) {
addOne(countMap, nums[i], hashTableSize);
}
for (int i = 0; i < hashTableSize; ++i) {
if (countMap[i].count > numsSize/2){
return countMap[i].num;
}
}
return 0;
}
int rangedMajorityElement(int* nums, int start, int stop){
if(start == stop) return nums[start];
int mid = start +(stop - start) /2;
int leftMajorityElement = rangedMajorityElement(nums, start, mid);
int rightMajorityElement = rangedMajorityElement(nums, mid+1, stop);
if (leftMajorityElement == rightMajorityElement){
return leftMajorityElement;
}
int leftCount = 0;
for (int i = start; i <= stop; ++i) {
if (nums[i] == leftMajorityElement){
leftCount++;
}
}
int rightCount = 0;
for (int i = start; i <= stop; ++i) {
if (nums[i] == rightMajorityElement){
rightCount++;
}
}
return leftCount>rightCount?leftMajorityElement:rightMajorityElement;
}
int majorityElement(int* nums, int numsSize){
return rangedMajorityElement(nums, 0, numsSize-1);
}
分治法
int majorityElement(int* nums, int numsSize){
int num;
int count = 0;
for (int i = 0; i < numsSize; ++i) {
if (count == 0){
num = nums[i];
count = 1;
} else if (num == nums[i]){
count ++;
} else{
count --;
}
}
return num;
}
太强了,这个做法