剑指 Offer 39. 数组中出现次数超过一半的数字

125 阅读2分钟

题目

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

 

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

 

示例 1:

输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2

 

限制:

1 <= 数组长度 <= 50000

 

注意:本题与主站 169 题相同:leetcode-cn.com/problems/ma…

题解

如果这个数组是排序好的数组,就能很容易的统计处每个数字出现的次数,然后找出次数超过一半的数字,但排序的时间复杂度是O(NlogN) 不满足题目要求。

接下来我们从另外一个角度来解决这个问题,数组中有一个数字出现的次数超过数组长度的一半,也就是说他出现的额次数比其他所有数字出现的次数和还要多。

因此,可以考虑遍历数组的时候保存两个值,一个是数组中的数字,另一个是次数。 当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1; 如果下一个数字和我们之前保存的数字不相同,则次数减1。 如果次数为0, 那么我们需要保存下一个数字,并把次数设为1。这么做是由于我们要找的数字出现的次数比其他所有数字出现的次数之和还要多,那么要找的数字肯定是最后一次把数字设置为1时对应的数字

代码

/**
 * @param {number[]} nums
 * @return {number}
 */
var majorityElement = function(nums) {
    let result = nums[0];
    let times = 1;
    for (let i = 1; i < nums.length; i++) {
        if (nums[i] == result) {
            times++;
        } else if (times == 0) {
            result = nums[i];
        } else {
            times--;
        }
    }

    return result;
};

原题链接

剑指 Offer 39. 数组中出现次数超过一半的数字