C++实现LeetCode(169.求大多数)

 更新时间:2021年08月02日 14:50:11   作者:Grandyang  
这篇文章主要介绍了C++实现LeetCode(169.求大多数),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

[LeetCode] 169. Majority Element 求大多数

Given an array nums of size n, return the majority element.

The majority element is the element that appears more than ⌊n / 2⌋ times. You may assume that the majority element always exists in the array.

Example 1:

Input: nums = [3,2,3]
Output: 3

Example 2:

Input: nums = [2,2,1,1,1,2,2]
Output: 2

Constraints:

  • n == nums.length
  • 1 <= n <= 5 * 104
  • -231 <= nums[i] <= 231 - 1

Follow-up: Could you solve the problem in linear time and in O(1) space?

这是到求大多数的问题,有很多种解法,其中我感觉比较好的有两种,一种是用哈希表,这种方法需要 O(n) 的时间和空间,另一种是用一种叫摩尔投票法 Moore Voting,需要 O(n) 的时间和 O(1) 的空间,比前一种方法更好。这种投票法先将第一个数字假设为过半数,然后把计数器设为1,比较下一个数和此数是否相等,若相等则计数器加一,反之减一。然后看此时计数器的值,若为零,则将下一个值设为候选过半数。以此类推直到遍历完整个数组,当前候选过半数即为该数组的过半数。不仔细弄懂摩尔投票法的精髓的话,过一阵子还是会忘记的,首先要明确的是这个叼炸天的方法是有前提的,就是数组中一定要有过半数的存在才能使用,下面来看本算法的思路,这是一种先假设候选者,然后再进行验证的算法。现将数组中的第一个数假设为过半数,然后进行统计其出现的次数,如果遇到同样的数,则计数器自增1,否则计数器自减1,如果计数器减到了0,则更换下一个数字为候选者。这是一个很巧妙的设定,也是本算法的精髓所在,为啥遇到不同的要计数器减1呢,为啥减到0了又要更换候选者呢?首先是有那个强大的前提存在,一定会有一个出现超过半数的数字存在,那么如果计数器减到0了话,说明目前不是候选者数字的个数已经跟候选者的出现个数相同了,那么这个候选者已经很 weak,不一定能出现超过半数,此时选择更换当前的候选者。那有可能你会有疑问,那万一后面又大量的出现了之前的候选者怎么办,不需要担心,如果之前的候选者在后面大量出现的话,其又会重新变为候选者,直到最终验证成为正确的过半数,佩服算法的提出者啊,代码如下:

C++ 解法一:

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int res = 0, cnt = 0;
        for (int num : nums) {
            if (cnt == 0) {res = num; ++cnt;}
            else (num == res) ? ++cnt : --cnt;
        }
        return res;
    }
};

Java 解法一:

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

下面这种解法利用到了位操作 Bit Manipulation 来解,将这个大多数按位来建立,从0到31位,每次统计下数组中该位上0和1的个数,如果1多,那么将结果 res 中该位变为1,最后累加出来的 res 就是过半数了,相当赞的方法,参见代码如下:

C++ 解法二:

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int res = 0, n = nums.size();
        for (int i = 0; i < 32; ++i) {
            int ones = 0, zeros = 0;
            for (int num : nums) {
                if (ones > n / 2 || zeros > n / 2) break;
                if ((num & (1 << i)) != 0) ++ones;
                else ++zeros;
            }
            if (ones > zeros) res |= (1 << i);
        }
        return res;
    }
};

Java 解法二:

public class Solution {
    public int majorityElement(int[] nums) {
        int res = 0, n = nums.length;
        for (int i = 0; i < 32; ++i) {
            int ones = 0, zeros = 0;
            for (int num : nums) {
                if (ones > n / 2 || zeros > n / 2) break;
                if ((num & (1 << i)) != 0) ++ones;
                else ++zeros;
            }
            if (ones > zeros) res |= (1 << i);
        }
        return res;
    }
}

Github 同步地址:

https://github.com/grandyang/leetcode/issues/169

类似题目:

Majority Element II

参考资料:

https://leetcode.com/problems/majority-element/

https://leetcode.com/problems/majority-element/discuss/51613/O(n)-time-O(1)-space-fastest-solution

https://leetcode.com/problems/majority-element/discuss/51612/6-Suggested-Solutions-in-C++-with-Explanations

https://leetcode.com/problems/majority-element/discuss/51611/Java-solutions-(sorting-hashmap-moore-voting-bit-manipulation).

https://leetcode.com/problems/majority-element/discuss/51828/C++-solution-using-Moore's-voting-algorithm-O(n)-runtime-comlexity-an-no-extra-array-or-hash-table

到此这篇关于C++实现LeetCode(169.求大多数)的文章就介绍到这了,更多相关C++实现求大多数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言实现简易连连看游戏

    C语言实现简易连连看游戏

    这篇文章主要为大家详细介绍了C语言实现简易连连看游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • C++使用new和delete进行动态内存分配与数组封装

    C++使用new和delete进行动态内存分配与数组封装

    这篇文章主要介绍了C++使用new和delete进行动态内存分配与数组封装,运行期间才能确定所需内存大小,此时应该使用new申请内存,下面我们就进入文章学习具体的操作方法,需要的小伙伴可以参考一下
    2022-03-03
  • VisualStudio Community2019在安装的过程中无法进入安装界面的解决方法

    VisualStudio Community2019在安装的过程中无法进入安装界面的解决方法

    这篇文章主要介绍了VisualStudio Community2019在安装的过程中无法进入安装界面的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • C++中的const和constexpr详解

    C++中的const和constexpr详解

    C++ const 和 constexpr 的区别呢,constexpr表示这玩意儿在编译期就可以算出来(前提是为了算出它所依赖的东西也是在编译期可以算出来的)。而const只保证了运行时不直接被修改(但这个东西仍然可能是个动态变量)。下面我们来详细讲解下。
    2016-01-01
  • C字符串与C++中string的区别详解

    C字符串与C++中string的区别详解

    以下是对C字符串与C++中string的区别进行了详细的分析介绍,需要的朋友可以过来参考下
    2013-09-09
  • c++仿函数和函数适配器的使用详解

    c++仿函数和函数适配器的使用详解

    这篇文章主要介绍了c++仿函数和函数适配器的使用详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • C++示例讲解friend static const关键字的用法

    C++示例讲解friend static const关键字的用法

    静态成员static是解决同一个类的不同对象之间数据和函数共享问题。区分全局变量,全局变量也能实现数据共享,但安全性和封装性被破坏了,友元提供了不同类或对象的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制,const常引用-被引用的对象不能被更新
    2022-06-06
  • C语言实现手写字符串处理工具的示例代码

    C语言实现手写字符串处理工具的示例代码

    这篇文章主要为大家详细介绍了利用C语言实现手写字符串处理工具的相关资料,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以参考一下
    2022-09-09
  • C中qsort快速排序使用实例

    C中qsort快速排序使用实例

    在学习C++ STL的sort函数,发现C中也存在一个qsort快速排序,要好好学习下C的库函数啊
    2014-01-01
  • C++11中列表初始化机制的概念与实例详解

    C++11中列表初始化机制的概念与实例详解

    在我们实际编程中,我们经常会碰到变量初始化的问题,对于不同的变量初始化的手段多种多样,下面这篇文章主要给大家介绍了关于C++11中列表初始化机制的相关资料,需要的朋友可以参考下
    2021-11-11

最新评论