【剑指offer】【其他算法】39.数组中出现次数超过一半的数字

题目链接:https://leetcode-cn.com/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof/

循环抵消

因为数组中有一个数字出现的次数超过数组长度的一半,它出现的次数比所有其它数字出现的次数和还要多;
所以在遍历数组的时候,保存两个变量,次数和值,当遍历到一个数字:
1. 如果它与前一个数相同那么次数加1;
2. 如果不同,次数减1;
如果次数为0,那么需要保存的数下一个数,并把次数设置为1;

统计数字出现的个数cnt = 0, val = -1;
遍历数组中每个数字x
如果val = x, cnt++
如果val != x,
1. cnt != 0, cnt--;
2. cnt == 0, 更新val和cnt
时间复杂度O(N) 空间复杂度O(1)

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

快排的思想

如果数组排好序的话,出现最多的那个数就是这个数组的中位数
快速排序每次都是在数组中随机选择一个数字,然后调整数字的顺序,使得它左边的数都比它小,右边的数都比他大;
我们每次也从中随机选一个数,把它放到合适的位置;
1. 如果它的下标刚好等于n/2,那么这个数字是数组的中位数;
2. 如果它的下标刚好大于n/2, 那么中位数在它的左边;我们接着在它的左边找
3. 如果它的下标刚好小于n/2, 那么中位数在它的右边;我们接着在它的右边找

/*
有问题
class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int n = nums.size() - 1;
        int s = 0, e = n;
        int cur = partition(nums, s, e);

        int mid = n >> 1;
        while(cur != mid)
        {
            if(cur > mid)
            {
                e = cur - 1;
                cur = partition(nums, s, e);
            }
            else
            {
                s = cur + 1;
                cur = partition(nums, s, e);
            }
        }
        return nums[cur];
        // return 0;
    }
    int partition(vector<int>& nums, int l, int r)
    {
        if(l >= r) return -1;
        int x = nums[(l + r) >> 1];

        int i = l - 1, j = r + 1;
        while(i < j)
        {
            do i++; while(nums[i] < x);
            do j--; while(nums[j] > x);
            if(i < j) swap(nums[i], nums[j]), cout<< nums[i] << " " << nums[j] << "hello" << endl;
        }
        for(int i = l; i < r - l + 1; i++)
            cout << nums[i] << " ";
        cout << endl;
        cout << j << endl;
        return j;
    }
};
*/
posted @ 2020-04-19 14:15  NaughtyCoder  阅读(73)  评论(0)    收藏  举报