LeetCode169.求众数

转载链接:https://blog.csdn.net/qq_41231926/article/details/86479848

原题链接:https://leetcode-cn.com/problems/majority-element/description/

题目描述:

知识点:哈希表、分治算法、位运算、摩尔投票法

思路一:用哈希表记录各个数字出现的次数

时间复杂度和空间复杂度均是O(n)。

JAVA代码:


 
 
  1. public class Solution {
  2. public int majorityElement(int[] nums) {
  3. HashMap<Integer, Integer> hashMap = new HashMap<>();
  4. for ( int i = 0; i < nums.length; i++) {
  5. if(hashMap.containsKey(nums[i])){
  6. hashMap.put(nums[i], hashMap.get(nums[i]) + 1);
  7. } else{
  8. hashMap.put(nums[i], 1);
  9. }
  10. }
  11. for(Integer integer : hashMap.keySet()){
  12. if(hashMap.get(integer) > nums.length / 2){
  13. return integer;
  14. }
  15. }
  16. return 0;
  17. }
  18. }

LeetCode解题报告:

思路二:排序后直接返回最中间的数

时间复杂度是O(nlogn)。空间复杂度是O(1)。

JAVA代码:


 
 
  1. public class Solution {
  2. public int majorityElement(int[] nums) {
  3. Arrays.sort(nums);
  4. return nums[nums.length / 2];
  5. }
  6. }

LeetCode解题报告:

思路三:分治算法

需要注意的是,如果左半部分得到的众数和右半部分得到的众数不相同,需要统计两个众数在整个数组出现的具体次数才能判定谁是数组中的众数。

时间复杂度是O(nlogn)。空间复杂度是O(logn)。

JAVA代码:


 
 
  1. public class Solution {
  2. public int majorityElement(int[] nums) {
  3. return majorityElementRec(nums, 0, nums.length- 1);
  4. }
  5. private int majorityElementRec(int[] nums, int left, int right) {
  6. if (left == right) {
  7. return nums[left];
  8. }
  9. int mid = (right - left)/ 2 + left;
  10. int leftResult = majorityElementRec(nums, left, mid);
  11. int rightResult = majorityElementRec(nums, mid + 1, right);
  12. if (leftResult == rightResult) {
  13. return leftResult;
  14. }
  15. int leftCount = countInRange(nums, leftResult, left, right);
  16. int rightCount = countInRange(nums, rightResult, left, right);
  17. return leftCount > rightCount ? leftResult : rightResult;
  18. }
  19. private int countInRange(int[] nums, int num, int left, int right) {
  20. int count = 0;
  21. for ( int i = left; i <= right; i++) {
  22. if (nums[i] == num) {
  23. count++;
  24. }
  25. }
  26. return count;
  27. }
  28. }

LeetCode解题报告:

思路四:Boyer–Moore majority vote algorithm

时间复杂度和空间复杂度均是O(n)。

JAVA代码:


 
 
  1. public class Solution {
  2. public int majorityElement(int[] nums) {
  3. int result = nums[ 0];
  4. int count = 1;
  5. for ( int i = 1; i < nums.length; i++) {
  6. if( 0 == count){
  7. count = 1;
  8. result = nums[i];
  9. } else if(nums[i] == result){
  10. count++;
  11. } else{
  12. count--;
  13. }
  14. }
  15. return result;
  16. }
  17. }

LeetCode解题报告:

思路五:位运算

int型数由32位组成,对于每一位,不是1就是0。比如对于第i位,我们可以统计nums数组中的元素,其中第i位时1的数量是ones,而第i位是0的数量是zeros。根据题意,nums数组中必然存在众数,此数的出现次数大于n / 2(向下取整)。因此ones和zeros的值不可能相等。如果ones大于zeros,那么结果的第i位必然是1,否则结果的第i位必然是0。

时间复杂度是O(n)。空间复杂度是O(1)。

JAVA代码:


 
 
  1. public class Solution {
  2. public int majorityElement(int[] num) {
  3. int result = 0;
  4. for ( int i = 0; i < 32; i++) {
  5. int ones = 0, zeros = 0;
  6. for ( int j = 0; j < num.length; j++) {
  7. if ((num[j] & ( 1 << i)) != 0) {
  8. ones++;
  9. } else{
  10. zeros++;
  11. }
  12. }
  13. if (ones > zeros){
  14. result |= ( 1 << i);
  15. }
  16. }
  17. return result;
  18. }
  19. }

LeetCode解题报告:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值