微信公众号:路人zhang
扫码关注微信公众号

回复“面试手册”,获取本站PDF版

回复“简历”,获取高质量简历模板

回复“加群”,加入程序员交流群

回复“电子书”,获取程序员类电子书

当前位置: 算法 > 剑指offer > 剑指 offer 39. 数组中出现次数超过一半的数字

题目描述

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

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

示例 1:

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

限制:

1 <= 数组长度 <= 50000


算法

(模拟) O(n)

性质:出现次数超过一半 假设这个数是 A,其他数是 B,根据这个性质,我们可以做一个比喻,数 A 比做是钱,出现几次就是几块钱,数 B 比做商品,一件商品消费一块钱,那么遍历完整个数组,消费完全部商品,钱肯定会剩下。

代码实现:

  1. 用 val 存储重复出现的数,cnt 记录 val 出现的次数
  2. 遍历整个数组,如果 val 出现次数为 0,就从当前数 x 开始计数,val = x, cnt = 1表示当前数出现一次,如果当前数 x 等于 val x == val,出现次数加 1 cnt ++,否则出现次数减 1 cnt --
  3. 遍历完成后 val 中存储的就是答案

时间复杂度

遍历一遍数组,时间复杂度为 O(n)

空间复杂度

O(1)

C++ 代码

class Solution {
public:
    int moreThanHalfNum_Solution(vector<int>& nums) {
        int val = -1, cnt = 0;
        for (auto x : nums)
        {
            if (!cnt) val = x, cnt ++ ;
            else 
            {
                if (x == val) cnt ++;
                else cnt -- ;
            }
        }
        return val;
    }
};

Java 代码

class Solution {
    public int majorityElement(int[] nums) {
        int val = -1, cnt = 0;
        for (int x : nums) {
            if (cnt == 0) {
                val = x;
                cnt ++ ;
            } else {
                if (x == val) cnt++;
                else cnt -- ;
            }
        }
        return val;
    }
}

Python 代码

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        val = -1
        cnt = 0
        for x in nums:
            if cnt == 0:
                val = x
                cnt += 1
            else:
                if x == val:
                    cnt += 1
                else:
                    cnt -= 1
        return val

本文由读者提供Github地址:https://github.com/tonngw


点击面试手册,获取本站面试手册PDF完整版