[Leetcode] 169. Majority Element 解题报告

来源:互联网 发布:淘宝店保证金怎么交 编辑:程序博客网 时间:2024/05/22 00:09

题目

Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

You may assume that the array is non-empty and the majority element always exist in the array.

思路

虽然这道题目的官方难度是easy级别,但我感觉这道题目还是值得好好讨论一下,因为这里面可能会涉及到几个很不错的思想和算法。

1、暴力法:就是扫描数组,并记录每个数字出现的次数,一旦发现某一个数字的出现次数超过一半了,就返回。可以采用哈希表记录每个数字出现的次数。算法的时间复杂度是O(n),空间复杂度也是O(n)。然而,该方法只能作为和面试官开聊的开场白,要是作为最终解法就必挂无疑了。

2、基于快速排序的方法:经典的快速排序算法中的partition函数每次会把数组分成两个部分,并把一个值排在正确的位置上。而如果这个位置刚好在n/2处,那么这个数字必然是超过n/2次的数。这种方法同样可以处理寻求第K个的数。该方法的空间复杂度是O(1),但是时间复杂度最坏情况下可能达到O(n^2),平均复杂度是O(nlogn),相当于快速排序了。不过这里基于partition的思想很重要。

3、Moore投票法:设置一个计数器,并维护一个当前出现次数最多的数。在遍历数组的过程中,如果所遍历的数和当前数相等,则计数器加1,否则计数器减1。一旦发现计数器为0,则更新当前数。由于majority element的出现次数大于所有其它数的出现次数之和,所以当遍历完成数组之后,当前数必然是majority element。该算法的时间复杂度是O(n),空间复杂度是O(1),是该问题的最优解和正解。

代码

1、暴力法:

class Solution {public:    int majorityElement(vector<int>& nums) {        std::unordered_map<int, int> digits_map;    for (int i = 0; i < nums.size(); ++i) {        if (++digits_map[nums[i]] > nums.size() / 2) {            return nums[i];        }    }    return -1;    }};

2、基于快速排序的方法:

class Solution {public:    int majorityElement(vector<int>& nums) {        if (nums.size() == 0) {     // special case            return -1;        }        int start = 0, end = nums.size() - 1;        int index = partition(nums, start, end);        while(index != (nums.size() / 2)) {            if(index > nums.size()/2) {         // majority element will certainly be in the left part                end = index - 1;                index = partition(nums, start, end);            }            else if(index < nums.size()/2) {    // majority element will certainly be in the right part                start = index + 1;                index = partition(nums, start, end);            }        }        return nums[nums.size()/2];    }private:    int partition(vector<int>& nums, int begin, int end) {        int value = nums[begin];        while(begin < end) {            while(begin < end && value < nums[end]) {                --end;            }            if(begin < end) {                nums[begin++] = nums[end];            }            while(begin < end && value > nums[begin]) {                ++begin;            }            if(begin < end) {                nums[end--] = nums[begin];            }        }        nums[begin] = value;        return begin;    }};

3、Moore投票法:

class Solution {public:    int majorityElement(vector<int>& nums) {        if(nums.size() == 0) {            return -1;        }        int num = nums[0], count = 1;        for(int i = 1; i < nums.size(); ++i) {            if(nums[i] == num) {                ++count;            }            else {                --count;                if(count == 0) {                    num = nums[i];                    count = 1;                }            }        }        return num;    }};
原创粉丝点击