解题思路
我的做法是使用插入排序,使用O(n)的时间扫一遍排序后的数组就可以算出哪些数字出现超过n/3次。耗时主要是插入排序的耗时,空间消耗O(1).
也可以使用map,保存所有数字出现的次数,耗时O(n),空间消耗也O(n)。
这个题的标准做法是使用多数投票算法
提交代码(对数组排序后进行统计)
class Solution {
public List<Integer> majorityElement(int[] nums) {
List<Integer> res=new ArrayList<Integer>();
insertSort(nums);
int p1=0,p2=0,range=(int)Math.ceil(nums.length/3);
for(p2=0;p2<nums.length;p2++) {
if(nums[p2]!=nums[p1]) {
if(p2-p1>range) res.add(nums[p1]);
p1=p2;
}
}
if(p2-p1>range) res.add(nums[p1]);
return res;
}
public void insertSort(int[] nums) {
int i,j,tmp;
for(i=1;i<nums.length;i++) {
j=i;
while(j>=1&&nums[j]<nums[j-1]) {
tmp=nums[j];
nums[j]=nums[j-1];
nums[j-1]=tmp;
j--;
}
}
}
}
运行结果
提交代码(多数投票算法)
class Solution {
public List<Integer> majorityElement(int[] nums) {
List<Integer> res=new ArrayList<Integer>();
int candidate1=0,candidate2=1,count1=0,count2=0;
for(Integer num :nums) {
if(num==candidate1)
count1++;
else if(num==candidate2)
count2++;
else if(count1==0) {
candidate1=num;
count1=1;
}else if(count2==0) {
candidate2=num;
count2=1;
}
else {
count1--;count2--;
}
}
count1=0;count2=0;
for(Integer num:nums) {
if(num==candidate1)
count1++;
else if(num==candidate2)
count2++;
}
if(count1>nums.length/3) res.add(candidate1);
if(count2>nums.length/3) res.add(candidate2);
return res;
}
}