编程之美--水王(找出出现超过1/2的数)
这个题,在leetcode上也有。
主要有几种解答,最简单的就是 直接将数组排序,那么出现在中间的肯定是要找的数。。。这种时间复杂度是排序的o(nlgn);另一种思路是将这些数存在hash表中,key值为数组中的值,value是出现的次数,则大于1/2len就可以直接返回了。
一种较为简单的方法,也不用耗费多余的空间。每次删除两个数,最后剩下的就是出现次数超过1/2.
public int majorityElement(int[] num) { int major=num[0], count = 1; for(int i=1; i<num.length;i++){ if(count==0){ count++; major=num[i]; }else if(major==num[i]){ count++; }else count--; } return major; }
变式:找出一个数组中出现的大于1/3的数 出现的超过1/3的数不会超过两个
Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋
times. The algorithm should run in linear time and in O(1) space.
代码贴一下:
public class Solution { public List<Integer> majorityElement(int[] nums) { int len = nums.length; List<Integer> res=new ArrayList<>(); if(len==0) return res; int number1=nums[0]; int number2=nums[0]; int count1=0; int count2=0; for(int i=0;i<len;i++){ if(number1==nums[i]){ count1++; } else if(number2==nums[i]){ count2++; } else if(count1==0){ number1=nums[i]; count1=1; } else if(count2==0){ number2=nums[i]; count2=1; } else{ count1--; count2--; } } count1=0; count2=0; for(int i=0;i<len;i++){ if(nums[i]==number1) count1++; else if(nums[i]==number2) count2++; } if(count1>len/3) res.add(number1); if(count2>len/3) res.add(number2); return res; } }