[剑指-Offer] 39. 数组中出现次数超过一半的数字(多数投票算法、sort函数、代码优化)

文章目录

    • 1. 题目来源
    • 2. 题目说明
    • 3. 题目解析
      • 方法一:多数投票算法+ O ( n ) O(n) O(n)时间复杂度+最优解法
      • 方法二:sort()排序+ O ( l o g n ) O(logn) O(logn)时间复杂度+投机解法

1. 题目来源

链接:数组中出现次数超过一半的数字
来源:LeetCode——《剑指-Offer》专项

2. 题目说明

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

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

示例 1:

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

限制:

  • 1 <= 数组长度 <= 50000

3. 题目解析

方法一:多数投票算法+ O ( n ) O(n) O(n)时间复杂度+最优解法

算法思想相当简单,即不同的数两两抵消,超过一半的数字是抵消后剩余的数字,关于这个算法的详细介绍以及相关 OJ 这是博主的总结链接:[杂谈] 7. Majority Vote Algorithm 多数投票算法

参见代码如下:

// 执行用时 :20 ms, 在所有 C++ 提交中击败了82.68%的用户
// 内存消耗 :21.7 MB, 在所有 C++ 提交中击败了100.00%的用户

class Solution {
public:
    int majorityElement(vector<int> numbers) {
        int num = 0, count = 0;
        for (int i = 0; i < numbers.size(); i++) {
            if (count == 0) num = numbers[i];
            if (numbers[i] == num) count++;
            else count--;
        }
        return num;
    }
};

稍作改动并验证正确性版本:

// 执行用时 :20 ms, 在所有 C++ 提交中击败了82.68%的用户
// 内存消耗 :21.8 MB, 在所有 C++ 提交中击败了100.00%的用户

class Solution {
public:
    int majorityElement(vector<int> numbers) {
        int n = numbers.size();
        if (n == 0) 
            return 0;
        int num = numbers[0], count = 1;
        for (int i = 1; i < n; i++) {
            if (numbers[i] == num) 
                count++;
            else 
                count--;
            if (count == 0) {
                num = numbers[i];
                count = 1;
            }
        }
        // 经过上面的操作, 已经找到该数 num 了. 
        // 下面的操作是为了确认 num 确实是出现次数超过一半. 
        count = 0;
        for (int i = 0; i < n; i++) {
            if (numbers[i] == num) 
                count++;
        }
        if (count * 2 > n) 
            return num;
        return 0;
    }
};

方法二:sort()排序+ O ( l o g n ) O(logn) O(logn)时间复杂度+投机解法

sort() 排序最中间的数字肯定是超过一半的数字,但是 sort() 时间复杂度为 O ( l o g n ) O(logn) O(logn) 颇高。

参见代码如下:

// 执行用时 :24 ms, 在所有 C++ 提交中击败了62.85%的用户
// 内存消耗 :21.3 MB, 在所有 C++ 提交中击败了100.00%的用户

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        return nums[nums.size() >> 1];
    }
};

你可能感兴趣的:(#,《剑指-Offer》(第二版),《剑指-Offer》,多数投票算法,sort函数,代码优化)