算法(二)找出数组中元素数目超出一半的元素

题目如下:

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.

解题方法:

1. 最简单的方法,遍历整个数组,两层for循环,可以用set容器来排除前面已经出现过的元素,当重复数组元素很多时可以起到很好的效果,代码如下:

class Solution {
public:
    int majorityElement(vector<int> & nums) {
        int n = nums.size();
        set<int> temp;
        for (int i = 0; i < n; ++i) {
            if (temp.find(nums[i]) == temp.end()) {
                temp.insert(nums[i]);
                int count = 1;
                for (int j = i + 1; j < n; ++j) {
                    if (nums[j] == nums[i])
                        count++;
                }
                if (count > n / 2) {
                    return nums[i];
                }
            }
        }
        return 0;
    }
};

2. 只需要一层for循环,先用两个变量,一个majorElement记录当前认为的最多元素,初始化为第一个元素,一个number初始化为1,从第二个数开始遍历,遍历的元素与majorElement相同时加1,否则减去1。若numer小于0,表示当前majorElement已经小于已经遍历的元素一半,而在已经遍历元素当中,任一元素都小于已经遍历元素的一半。因此,真正的majorElement应当在未遍历的元素中占据超过一半的元素。所以,将majorElement重新设置为此时的元素值,number初始化为1,继续遍历。代码如下:

class Solution {
public:
    int majorityElement(vector<int> & nums) {
        int majorNumber = nums[0];
        int j = 1;
        for (int i = 1; i < nums.size(); ++i) {
            if (nums[i] == majorNumber)
                j++;
            else
                j--;
            if (j == -1) {
                majorNumber = nums[i];
                j = 1;
            }
        }
        return majorNumber;
    }
};

3. 数组元素数组超过一半的元素应当在排好序的数组的中间位置,所以可以用排序算法来解决这个问题。此外,此题可以不对数组进行完全排序,用冒泡排序可以排出前middle个最大元素即可。用快速排序只需让index == middle即可找到所要元素。类似快拍的方法代码如下:

class Solution {
public:
    int majorityElement(vector<int> & nums) {
        int high = nums.size() - 1;
        int low = 0;
        int middle = high / 2;
        int index = partition(nums, 0, high);
        while (index != middle)
        {
            if (index < middle)
                low = index + 1;
            else
                high = index - 1;
            index = partition(nums, low, high);
        }
        return nums[index];
    }
    int partition(vector<int> & nums, int low, int high) {
        if (low >= high)
            return low;
        int last_small = low;
        for (int i = low + 1; i <= high; ++i) {
            if (nums[i] < nums[low]) {
                last_small++;
                swap(nums, i, last_small);
            }
        }
        swap(nums, last_small, low);
        return last_small;
    }
    void swap(vector<int> & nums, int a, int b) {
        int temp = nums[a];
        nums[a] = nums[b];
        nums[b] = temp;
        return;
    }
};

注意:当有大量重复数据时,最后一种方法可能会出现运行超时的问题。

你可能感兴趣的:(算法题目)