【LeetCode】169.Majority Element
题目:
给定一个大小为n的数组,找出其中的majority element。majority element是指在数组中出现超过n/2次的元素。
例1:
输入:[3,2,3]
输出:3
例2:
输入:[2,2,1,1,1,2,2]
输出:2
思路:
利用栈来求解。分3种情况:
- 栈为空,入栈;
- 栈顶元素等于当前元素,入栈;
- 否则,出栈。
最后栈中剩下的元素即是所求。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int majorityElement(int* nums, int numsSize) {
int* stack = malloc(sizeof(int) * numsSize); //栈
int top = -1; //初始栈为空
for (int i=0; i<numsSize; i++) {
if (top == -1) { //case1
stack[++top] = nums[i];
}
else if (stack[top] == nums[i]) { //case2
stack[++top] = nums[i];
}
else { //case3
top--;
}
}
return stack[0];
}
int main(){
int nums[] = {1,2,1,2,2,3,2};
int result = majorityElement(nums, 7);
printf("The majority element is %d.\n", result);
return 0;
}
结果:
可以看到效率还是不错的。
算法时间复杂度为O(n),这是必须的,因为要把数组遍历一次。
空间复杂度为O(n),因为构造了与数组等大的栈,最坏的情况是数组全部入栈。
其实这个算法还可以改进,将空间复杂度降到O(1)。
改进思路如下:
其实并不需要真的构造一个栈,只需要一个“虚拟”的栈就可以达到目的。
可以设置一个变量cand表示当前栈中的元素,用另一个变量count表示当前栈中元素的个数,其实就是cand的个数。
3种情况同上:
- 栈空,入栈。修改cand,count++;
- 栈顶元素等于当前元素,入栈。不用修改cand,count++;
- 否则,出栈。count--。
最后cand即是所求。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int majorityElement(int* nums, int numsSize) {
int cand, count = 0;
for (int i=0; i<numsSize; i++) {
if (count == 0) { //case1
cand = nums[i];
count++;
}
else if (cand == nums[i]) { //case2
count++;
}
else { //case3
count--;
}
}
return cand;
}
int main(){
int nums[] = {1,2,1,2,2,3,2};
int result = majorityElement(nums, 7);
printf("The majority element is %d.\n", result);
return 0;
}
这样,就把空间复杂度降到了O(1)。
推荐一位干货up主:正月点灯笼
少一些功利主义的追求,多一些不为什么的坚持