LeetCode_Boyer-Moore 投票算法_中等_229.求众数 II

亦凉 2023-10-06 18:50 160阅读 0赞

目录

  • 1.题目
  • 2.思路
  • 3.代码实现(Java)

1.题目

给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。
进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1)的算法解决此问题。

示例 1:
输入:[3,2,3]
输出:[3]

示例 2:
输入:nums = [1]
输出:[1]

示例 3:
输入:[1,1,1,3,3,2,2,2]
输出:[1,2]

提示:
1 <= nums.length <= 5 * 104
-109 <= nums[i] <= 109

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/majority-element-ii

2.思路

(1)哈希表
① 创建一个哈希表 hashMap,其中键 / 值为nums中的整数 / 该整数目前出现的次数,再创建一个保存结果的动态数组 res;
② 遍历数组 nums,使用 put() 函数将当前整数nums[i]以及它目前出现的次数当作键值对添加到 hashMap 中(如果之前有添加过相同的Key,put() 方法会用新值替换旧值);
③ 使用 get() 获取当前整数出现的次数,如果次数大于 nums.length/3 且 res 中没有该整数,则将其添加到 res 中,并继续遍历。
④ 遍历数组 nums 结束后最后返回 res 即可。

(2)Boyer-Moore 投票算法
思路参考本题官方题解。

3.代码实现(Java)

  1. //思路1————哈希表
  2. public List<Integer> majorityElement(int[] nums) {
  3. int length = nums.length;
  4. ArrayList<Integer> res = new ArrayList<Integer>();
  5. HashMap<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
  6. for (int i = 0; i < length; i++) {
  7. if (res.contains(nums[i])) {
  8. continue;
  9. }
  10. //put(Key,value):如果之前有添加过相同的Key,put()方法会用新值替换旧值,返回的是旧值
  11. //getOrDefault(key):获取指定key对应对value,如果找不到key,则返回设置的默认值
  12. hashMap.put(nums[i], hashMap.getOrDefault(nums[i], 0) + 1);
  13. if (hashMap.get(nums[i]) > length / 3 && !res.contains(nums[i])) {
  14. res.add(nums[i]);
  15. }
  16. }
  17. return res;
  18. }
  19. //思路2————Boyer-Moore 投票算法,其时间复杂度为 O(n)、空间复杂度为 O(1)
  20. public List<Integer> majorityElement(int[] nums) {
  21. //利用反证法可以推断出满足题目条件的元素最多只有两个,我们设为 ele1 和 ele2
  22. int ele1 = 0;
  23. int ele2 = 0;
  24. //设 vote1 和 vote2 分别为 ele1 和 ele2 的赞成票数
  25. int vote1 = 0;
  26. int vote2 = 0;
  27. for (int num : nums) {
  28. if (vote1 > 0 && num == ele1) {
  29. //num 为第一个元素,则票数加1
  30. vote1++;
  31. } else if (vote2 > 0 && num == ele2) {
  32. //num 为第一个元素,则票数加1
  33. vote2++;
  34. } else if (vote1 == 0) {
  35. //选择第一个元素
  36. ele1 = num;
  37. vote1++;
  38. } else if (vote2 == 0) {
  39. //选择第二个元素
  40. ele2 = num;
  41. vote2++;
  42. } else {
  43. //三个元素 ele1、ele3、num 互不相同,则其票数减1
  44. vote1--;
  45. vote2--;
  46. }
  47. }
  48. //cnt1 和 cnt2 分别记录元素 ele1 和 ele2 出现的次数
  49. int cnt1 = 0;
  50. int cnt2 = 0;
  51. for (int num : nums) {
  52. if (vote1 > 0 && num == ele1) {
  53. cnt1++;
  54. }
  55. if (vote2 > 0 && num == ele2) {
  56. cnt2++;
  57. }
  58. }
  59. //检查元素出现的次数是否满足要求
  60. List<Integer> res = new ArrayList<>();
  61. if (vote1 > 0 && cnt1 > nums.length / 3) {
  62. res.add(ele1);
  63. }
  64. if (vote2 > 0 && cnt2 > nums.length / 3) {
  65. res.add(ele2);
  66. }
  67. return res;
  68. }

发表评论

表情:
评论列表 (有 0 条评论,160人围观)

还没有评论,来说两句吧...

相关阅读

    相关 229. II

    给定一个大小为 n 的整数数组,找出其中所有出现超过 `⌊ n/3 ⌋` 次的元素。 进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1)的算法解决此问题。 示例

    相关 leetcode II

    给定一个大小为 n 的数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。 说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1)。 示例 1: 输入: \[