基本思想
在每一轮投票过程中,从数组中删除两个不同的元素,直到投票过程无法继续,此时数组为空或者数组中剩下的元素都相等。
如果数组为空,则数组中不存在主要元素(数组中占比超过一半的元素);
如果数组中剩下的元素都相等,则数组中剩下的元素可能为主要元素。
算法步骤
- 先用stream流将数组排序后转化成列表list
- 定义两个变量i和j作为指针,i指向list队头,j指向list队尾。
- 遍历list,如果指针下标对应元素不相等,则删除这两元素(这里为什么删除队尾的时候要-1,因为已经删了队头i,此时list长度发生了变化,j不-1就会越界),并重新让i和j指向队头队尾;如果相等则在list不越界情况下,i++,j--。为了提高效率,当i==j时说明指向同一元素直接跳出循环。
- 循环结束后,判断list是否为空,为空说明list的元素都不一样,没有主要元素,直接返回-1;若不为空,说明list里都是相同的元素了,取第一个,遍历原数组,统计第一个元素在原数组中出现的次数,若小于原数组长度的一半(这里要用nums.length/2.0,为什么是2.0?因为除法是向下取整,避免出现误差要精确一点)则返回-1;否则说明list中的元素是主要元素。
代码如下
remove的时候注意remove有2种参数,一种是下标,一种是元素。因为元素类型正好是Integer,所以不管填下标或是元素都会默认成下标。正好符合我们的需求。若你需要删除元素,看我这篇文章Java增强for循环遍历集合删除指定值不安全问题_list<integer>增强for删除一个内容-CSDN博客
List<Integer> list = Arrays.stream(nums).sorted().boxed().collect(Collectors.toList());
for(int i=0, j=list.size()-1;i<list.size()&&j>0;){
if(list.get(i)-list.get(j)!=0){
// 移除下标为i和j的元素
list.remove(i);
list.remove(j-1);
i=0;
j=list.size()-1;
}else{
if(i<list.size()) i++;
if(j>0) j--;
}
if(i==j) break;
}
if(list.isEmpty()) return -1;
int count=0;
for(int num:nums){
if(num==list.get(0)) count++;
}
if(count<nums.length/2.0) return -1;
return list.get(0);