Majority Number II——算法练习

来源:互联网 发布:python idle 清屏 编辑:程序博客网 时间:2024/06/10 04:17

No.1-2 Majority Number II
Given an array of integers, the majority number is the number that occurs
more than 1/3 of the size of the array. Find it.

Note There is only one majority number in the array

Example For [1, 2, 1, 2, 1, 3, 3] return 1

/** *  * @author 风的流向 *  */public class MajorityNumber2 {    /**     * @param nums     *            : A list of integers     * @return: The majority number that occurs more than 1/3     */    static public int majorityNumber(ArrayList<Integer> nums) {        // 想不到时间复杂度为n,空间复杂度为1的做法了,这里只好使用空间换时间的hash表去做        Map<Integer, Integer> map = new HashMap<>();        int count = nums.size() / 3;        for (Integer num : nums) {            int sum = 1;            if (map.containsKey(num))                sum = map.get(num) + 1;            map.put(num, sum);            if (sum > count) {                return num;            }        }        return -1;    }}

【附:开课吧算法讨论组参考答案】
http://www.douban.com/group/topic/68473876/

[题解] Majority Number 贪心算法
总体思路就是从数组第一个数字开始,并把第一个数字作为majority candidate(众数候选者),然后用一个计数器统计majority candidate的出现次数。
int idxMajority = 0; //指向众数候选者
int cntMajority = 1; //计数器

然后开始遍历整个数组,如果后面的数字和majority candidate一致,则计数器加1,继续往后走;

如果后面的数字和majority candidate不一致,则计数器减1,此时要判断一下计数器是否为0:
a. 如果不为0,则继续往后走;
b. 如果为0,那么说明前面的子数组(从idxMajority到当前index)中有一半是同一个数字,即为majority candidate,另一半为不同的数字,此时如果舍弃前面的子数组,则并不会导致majority number产生变化。
进一步解释一下,这里其实还会有两种情况,即:
a’ 众数候选者,其实不是真正的众数,那么舍弃的子数组包含的都不是众数,这样不会对最终的结果影响。
b’ 众数候选者,是真正的众数,也不会对最终的结果产生影响。举个例子,7局4胜的乒乓球比赛,如果前两局打成1比1平,那么我们可以认为7局4胜,就变成了5局3胜,前面打的两局对整个比赛的结果没有影响,双方又回到了起跑线上。

直到循环结束,idxMajority指向的数组元素,即为majority candidate。

此题的关键为贪心策略 - 如何在遍历过程中保证局部最优解为整体最优解,即在循环结束时,所保持的majority candidate和原始数组的majority candidate是一样的,或者说前面舍弃的子数组,不会导致majority number有变化。

参考代码:

int majorityNumber(vector<int> nums) {     // write your code here     int idxMajority = 0;     int cntMajority = 1;     for(int i = 1; i < nums.size(); i++)     {         if(nums[idxMajority] == nums[i])             cntMajority ++;         else             cntMajority --;         if(cntMajority == 0)         {             i++;             idxMajority = i;             cntMajority = 1;         }     }     return nums[idxMajority]; } 

测试为19ms

ii和iii应该是类似的解法变形。
提示是iii里的复杂度要求为
O(n) time and O(k) extra space

0 0