leetcode刷题笔记
力扣169题—多数元素
题目
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出
现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/majority-element
示例
示例1
输入: [3,2,3]
输出:3
示例2
输入: [2,2,1,1,1,2,2]
输出:2
题意分析
题目上说给定的数组总是存在多数元素,说明这个元素是一定会存在的,按照数学的思维的话,那可以理解我们平常所说的众数。因为众数是最多的。那我们可以往众数这个方向的思路去寻找
题解思路
- 一种是我们可以先将数组排序好,然后取中间元素的下标,因为题目说了,众数的次数是大于 n/2 的,那么无论数组长度是奇数还是偶数,都是取中间元素的下标
- 哈希表实现,我们可以利用哈希表的映射来找到次数最多的元素,利用其键值对来保存元素的值和出现的次数,这样我们遍历数组的时候,顺便检查这个小标的元素从哈希表取出来的值是否大于n/2
- 用栈实现,这个思路跟投票法差不多,即假设这个多数元素即为栈顶元素,则遍历数组,为栈顶元素则入队,否则出队。(此方法参考一位leetcode大神的实现)
- 以上三种方法的空间复杂度都无法达到O(1)的要求,即使是栈实现,也要开辟一段栈空间。读者若想了解空间为O(1)的算法,可以去了解一下投票算法。
代码
/*
* 排序
* 用到数组的工具类排序方法
* time O(nlogn)
* space O(logn)
*/
public static int majorityElement1(int[] nums) {
Arrays.sort(nums);
return nums[nums.length >> 1];
}
/*
* 哈希表
* time O(n)
* space O(n)
*/
public static int majorityElement2(int[] nums) {
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
int current = -1;
for (int i = 0; i < nums.length; i++) {
if (map.containsKey(nums[i])) {
map.put(nums[i], map.get(nums[i]) + 1);
}else {
map.put(nums[i], 1);
}
if (map.get(nums[i]) > nums.length >> 1) {
current = i;
}
}
return nums[current ];
}
public static int majorityElement3(int[] nums) {
Stack<Integer> stack = new Stack<Integer>();
for (int i = 0; i < nums.length; i++) {
//判断栈是否为空或者当前元素是否为栈顶元素
if (stack.isEmpty() || nums[i] == stack.peek()) {
stack.push(nums[i]);
}else {
stack.pop();
}
}
return stack.peek();
}