《找出整型数组中占比超过一半的数》题目解析| 豆包MarsCode AI刷题

95 阅读4分钟

题目解析

问题描述

小R从班级中抽取了一些同学,每位同学都会给出一个数字。已知在这些数字中,某个数字的出现次数超过了数字总数的一半。现在需要你帮助小R找到这个数字。

测试样例

样例1:array = [1, 3, 8, 2, 3, 1, 3, 3, 3],输出:3

样例2:array = [5, 5, 5, 1, 2, 5, 5],输出:5

样例3:array = [9, 9, 9, 9, 8, 9, 8, 8],输出:9

解题思路

摩尔投票算法:摩尔投票算法是一种用于解决“多数元素”问题的经典算法。其核心思想是通过抵消不同的元素来找到出现次数超过一半的元素。

1、初始化

候选元素 candidate 初始化为 0。

计数器 count 初始化为 0。

2、遍历数组

如果 count 为 0,将当前元素设为 candidate。

如果当前元素等于 candidate,则 count 加 1。

否则,count 减 1。

3、返回结果:

最终 candidate 就是我们要找的元素。

图解示例

假设输入数组为 [1, 3, 8, 2, 3, 1, 3, 3, 3]

288-02 232234.png 最终 candidate 为 3,即数组中出现次数超过一半的元素。

代码详解

    public static int solution(int[] array) {
        // 初始化候选元素和计数器
        int candidate = 0;
        int count = 0;

        // 遍历数组
        for (int num : array) {
            // 如果计数器为0,设置当前元素为候选元素
            if (count == 0) {
                candidate = num;
            }
            // 如果当前元素等于候选元素,计数器加1
            if (num == candidate) {
                count++;
            } else {
                // 否则,计数器减1
                count--;
            }
        }

        // 返回候选元素
        return candidate;
    }

    public static void main(String[] args) {
        // 测试用例
        System.out.println(solution(new int[]{1, 3, 8, 2, 3, 1, 3, 3, 3}) == 3);
    }
}

代码解释

1、初始化

int candidate = 0; int count = 0;

candidate 用于存储当前的候选元素; count 用于记录候选元素的出现次数。

2、遍历数组


    if (count == 0) {

        candidate = num;

    }

    if (num == candidate) {

        count++;

    } else {

        count--;

    }

}

3、返回结果

return candidate;

最终 candidate 就是我们要找的元素。

测试用例

    // 测试用例
    System.out.println(solution(new int[]{1, 3, 8, 2, 3, 1, 3, 3, 3}) == 3);
}

该测试用例验证了代码的正确性,输出结果为 true,表示代码正确找到了出现次数超过一半的元素。

总结

为什么摩尔投票算法有效?

摩尔投票算法的核心在于“抵消”。假设数组中存在一个出现次数超过一半的元素 x,那么在遍历数组的过程中,所有非 x 的元素都会被 x 抵消掉。具体来说: 如果当前元素是 x,计数器 count 加 1。 如果当前元素不是 x,计数器 count 减 1。 由于 x 的出现次数超过一半,因此在遍历结束后,count 一定大于 0,且 candidate 就是 x。 算法的正确性 初始化:candidate 和 count 初始化为 0,表示当前没有候选元素。 遍历过程: 如果 count 为 0,表示当前没有候选元素,将当前元素设为候选元素。 如果当前元素等于候选元素,计数器加 1。 如果当前元素不等于候选元素,计数器减 1。 返回结果:遍历结束后,candidate 就是我们要找的元素。

摩尔算法总结

摩尔投票算法的核心在于通过“抵消”不同元素的方式,最终留下出现次数超过一半的元素。假设存在这样一个多数元素,那么在遍历数组的过程中,任何非多数元素与其抵消一次后,多数元素仍然会保持优势(即出现次数仍然最多)。摩尔投票算法不仅适用于找出数组中出现次数超过一半的元素,还可以扩展到其他问题中,如找出出现次数最多的元素(如果存在的话,且出现次数大于等于n/k,其中k是一个常数)。提供的示例代码很好地实现了摩尔投票算法。通过遍历数组,并根据当前元素与候选元素的关系更新计数器和候选元素,最终得到了出现次数超过一半的元素。摩尔投票算法是一种高效且简洁的解决“多数元素”问题的算法。其核心思想在于通过抵消不同元素来找出多数元素,具有线性时间复杂度和常数空间复杂度的优势。在实际应用中,摩尔投票算法具有广泛的应用前景和重要的实用价值。