题目解析
在这道题中,我们要在一个整型数组中找出占比超过一半的元素,即这个元素在这个数组中出现的次数是要大于这个数组一半的长度,假设这个数组有n个元素,那么要找出出现次数大于n/2的数
输入:
array = [1, 3, 8, 2, 3, 1, 3, 3, 3]
输出:3
输入:
array = [5, 5, 5, 1, 2, 5, 5]
输出:5
解题思路
MarsCode AI提示可以利用摩尔投票算法来高效地找到这个元素。该算法的基本思想是通过维护一个候选者和一个计数器来逐步确定最终的候选者,适用于寻找数组中出现频率最高的元素。
思路如下:
第一步:选择数组的第一个元素作为初始候选者,并将计数器初始化为1。
第二步: 从数组的第二个元素开始,遍历整个数组。 对于每个元素: 如果当前元素与候选者相同,计数器加1。 如果不同,计数器减1。 如果计数器减到0,更新候选者为当前元素,并重置计数器为1。
第三步: 在遍历结束后,候选者即为所求的元素,返回结果,因为题目保证有一个元素的出现次数超过 n/2。
代码详解
算法主体部分
public static int solution(int[] array) {
// Edit your code here
int index=array[0];
int count=1;
for(int i=1;i<array.length;i++){
if (array[i]==index) {
count++;
}
else{
count--;
}
if (count == 0) {
index= array[i];
count = 1;
}
}
return index;
}
具体解释:
int index=array[0]; int count=1;
index变量用于存储当前认为的“候选者”元素,最开始初始化为数组的第一个元素。count变量用于计数初始候选者的出现次数,初始为1
for(int i=1;i<array.length;i++)
从数组的第二个元素(索引为1)开始遍历到最后一个元素。
if (array[i] == candidate) { count++; } else { count--; }
- 如果当前元素与候选者相等(即
array[i] == candidate),计数器递增,表示候选者的出现次数增加。 - 如果当前元素与候选者不相等,计数器递减,表示当前候选者的出现次数可能减少。
if (count == 0) { index= array[i]; count = 1; }
- 当计数器
count减到0时,表示当前候选者的出现次数和其他元素相抵消了,这时我们要更新候选者为当前的元素,并重置计数器为1,开始计算新的候选者出现的次数。
return index;
- 当遍历完成后,将返回最后确认的候选者
完整程序代码
public class Main {
public static int solution(int[] array) {
int index=array[0];
int count=1;
for(int i=1;i<array.length;i++){
if (array[i]==index) {
count++;
}
else{
count--;
}
if (count == 0) {
index= array[i];
count = 1;
}
}
return index;
}
public static void main(String[] args) {
System.out.println(solution(new int[]{1, 3, 8, 2, 3, 1, 3, 3, 3}) == 3);
}
}
总结
数组操作: 理解如何遍历数组,访问每个元素。
条件语句:使用 if-else 语句来判断当前元素是否与候选者相同,并据此更新计数。 计数器:
利用计数器来跟踪候选者的出现次数,理解计数的增减逻辑。
候选者更新机制: 当计数器减为零时更新候选者,理解其背后的原理和算法逻辑。
时间复杂度:该算法的时间复杂度为 O(n),空间复杂度为O(1),因为只使用了常量级的额外空间。
MarsCode AI在写题的过程中给我提供了许多帮助,在我思路不清晰时,给我提示要用摩尔投票算法,结合AI辅助能够更好地学习,系统性提升编程能力,让我受益颇深。