2024/5/21 起床走到阳台,外面绵柔细雨,手探出去,似乎感受不到。刚到实验室,窗外声音放大,雨大了。昨天的两题任务中断了,由于下雨加晚上有课。这样似乎也好,不让我有一种被强迫的感觉,随心所欲些也好,做题!
1、题目描述
2、逻辑分析
题目要求就是找出在数组中数量占比大于整个数组长度n的一半的元素。我的思路:第一步:将数组里面的元素遍历记录出现的个数;第二步:将他们与n/2比较。
在这里我突然又想到:数量超过一般的元素具有唯一性,那么算法可不可以优化一下:将数组中存在数量最多的元素来跟n/2比较。这里使用哈希表。
3、代码演示
public int majorityElement ( int [ ] nums) { Map < Integer , Integer > counts = countNums ( nums) ; Map. Entry < Integer , Integer > majorEntry = null ; for ( Map. Entry < Integer , Integer > entry : counts. entrySet ( ) ) { if ( majorEntry == null || entry. getValue ( ) > majorEntry. getValue ( ) ) { majorEntry = entry; } } return majorEntry. getKey ( ) ; } private Map < Integer , Integer > countNums ( int [ ] nums) { Map < Integer , Integer > counts = new HashMap < Integer , Integer > ( ) ; for ( int num : nums) { if ( ! counts. containsKey ( num) ) { counts. put ( num, 1 ) ; } else { counts. put ( num, counts. get ( num) + 1 ) ; } } return counts; }
这里使用了哈希表将元素作为键,元素的数量作为值。然后遍历哈希表,找到键值对中值最大的元素,最后返回该元素。技术难点是对哈希表还是不够熟练,特别是map.entry这里,都不知道还可以这样用。
时间复杂度:O(n),空间复杂度:O(n)。
这道题的解法好多啊,还有:排序、随机化、分治、Boyer-Moore 投票算法。
下面我们主要来说一下最后一个Boyer-Moore 投票算法,也称为摩尔投票算法。官方的思路解法太过于官方,这里选取了其他题解:
下面直接看代码:
public int majorityElement ( int [ ] nums) { int count = 0 ; Integer candidate = null ; for ( int num : nums) { if ( count == 0 ) { candidate = num; } count += ( num == candidate) ? 1 : - 1 ; } return candidate; }
时间复杂度:O(n),空间复杂度:O(1)。