题目:
主元素I:给定一个整型数组,找出主元素,它在数组中的出现次数严格大于数组元素个数的二分之一。
主元素II:给定一个整型数组,找到主元素,它在数组中的出现次数严格大于数组元素个数的三分之一。
主元素III:给定一个整型数组,找到主元素,它在数组中的出现次数严格大于数组元素个数的1/k。
分析:
对于第一题,采用抵消法,一旦发现数组中存在两个不同的数,就都删除,直到剩下的数都一样,此时剩下的元素就是主元素,因为每次抵消操作之后,剩下来的数种,主元素一定也还是超过一半的。具体实现的时候,记录一个candidate和其出现的次数count,遍历每个数,如果count==0,则把candidate置为遍历到的数,否则看遍历到的数和candidate是否相等,如果相等,则count++,否则count--(抵消),遍历结束后,candidate就是主元素。
public class Solution { /* * @param nums: a list of integers * @return: find a majority number */ public int majorityNumber(List<Integer> nums) { // write your code here int count=1; int temp=nums.get(0); for(int i=1;i<nums.size();i++){ if(count==0){ temp=nums.get(i); count=1; }else if(temp==nums.get(i)){ count++; }else{ count--; } } return temp; } }
对于第二题,依然采用抵消法,如果三个数不同,就三个数都去除,因此记录2个数,及其各自出现的次数即可。
public class Solution { /* * @param nums: a list of integers * @return: The majority number that occurs more than 1/3 */ public int majorityNumber(List<Integer> nums) { // write your code here int candidate1=0,candidate2=0; int count1,count2; count1=count2=0; for(int i=0;i<nums.size();i++){ if(candidate1==nums.get(i)){ count1++; }else if(candidate2==nums.get(i)){ count2++; }else if(count1==0){ candidate1=nums.get(i); count1=1; }else if(count2==0){ candidate2=nums.get(i); count2=1; }else{ count1--; count2--; } } count1=0;count2=0; for(int i=0;i<nums.size();i++){ if(nums.get(i)==candidate1) count1++; else if(nums.get(i)==candidate2) count2++; } return (count1>count2)?candidate1:candidate2; } }
第三题也可以采用相同的方法,除此之外,还可以通过hashmap实现,需要O(n)的空间复杂度和O(n)的时间复杂度,而之前用的抵消法只需要O(1)的空间复杂度。
首先计算出阈值,然后用hashmap存放值以及出现的次数,一旦等于阈值就返回该数。
public class Solution { /** * @param nums: A list of integers * @param k: An integer * @return: The majority number */ public int majorityNumber(List<Integer> nums, int k) { // write your code here int count=(int)Math.ceil(nums.size()/k); HashMap<Integer,Integer> hashMap=new HashMap<>(); for(int i=0;i<nums.size();i++){ if(!hashMap.containsKey(nums.get(i))){ hashMap.put(nums.get(i),1); }else{ int val=hashMap.get(nums.get(i)); if(val+1>count){ return nums.get(i); } hashMap.put(nums.get(i),++val); } } return 0; } }