153. Find Minimum in Rotated Sorted Array\229. Majority Element II\Moore's voting algorithm

153. Find Minimum in Rotated Sorted Array

题目描述

一个已经排好序的数组进行了旋转,然后找到最小的元素。

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Find the minimum element.

You may assume no duplicate exists in the array.

代码实现

暴力法:复杂度O(n)

class Solution {
public:
    int findMin(vector<int>& nums) {
        int len = nums.size();
        if(!len)  return 0;
        int res = nums[0];
        for(int i = 1; i < len; i++) if(res >= nums[i])  return nums[i];
        return res;
    }
};

使用二分法的话,那么就是log(N)。

class Solution {
public:
    int findMin(vector<int>& nums) {
        int lo = 0, hi = nums.size() - 1, mid;
        while(lo < hi) {
            mid = (lo + hi) >> 1;
            if(nums[mid] > nums[hi])  lo = mid + 1;
            else hi = mid;
        }
        return nums[lo];
    }
};

229. Majority Element II

题目描述

Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space.

Hint:

  • How many majority elements could it possibly have?
  • Do you have a better hint? Suggest it!

代码实现

原本题意是要求使用O(1)的space,这里我是用了O(n)的space。使用set实现。

class Solution {
public:
    vector<int> majorityElement(vector<int>& nums) {
        unordered_map<int, int> um;
        vector<int> res;
        int n = nums.size(), tar = floor(n/3);
        for(int i = 0; i < n; i++) {
            if(um.count(nums[i]) && um[nums[i]] != -1) {
                um[nums[i]]++;
                if(um[nums[i]] > tar) { res.push_back(nums[i]); um[nums[i]] = -1; }
            }
            else if(!um.count(nums[i])) {  
                um[nums[i]] = 1;
                if(um[nums[i]] > tar) { res.push_back(nums[i]); um[nums[i]] = -1; }
            }
        }
        return res;
    }
};

以上的方法明显不符合space O(1)的实现,所以在这里使用了一种叫做:Moore’s voting algorithm.

如果是超过半数以上的数是同一元素,那么就可以有以下实现:【2】

int majorityElement(vector<int> &num)
{
    int curIdx = 0, count = 1;
    for (int i = 1; i < num.size(); ++i)
    {
        num[i] == num[curIdx] ? ++count : --count;
        if (!count)
        {
            curIdx = i;
            count = 1;
        }
    }

    return num[curIdx];
}

使用同样的方法,leetcode上有个人做了大于n/k的通用做法:

class Solution {
private:    
    vector<int> majorityElement(vector<int>& nums, const int k) {
        const int size_n = nums.size();
        vector<int> result;
        unordered_map<int, int> cand;

        for (int i = 0; i < size_n; i++) {
            // 初始化的值都是0     
            cand[nums[i]]++;
            if (cand.size() == k) {
                // 每次存了k个数,就把只有一次的踢掉
                for (auto it = cand.begin(); it != cand.end(); ) {
                    if (--(it->second) == 0) it = cand.erase(it);
                    else it++;
                }
            }
        }
        // 把筛选之后的数据值置为0为接下来计算出现次数
        for (auto& item : cand) item.second = 0;
        for (auto& item : nums) 
            if (cand.count(item) > 0) cand[item]++;
        for (auto& item : cand) 
            if (item.second > size_n / k) result.emplace_back(item.first);
        return result;
    }
public:
    vector<int> majorityElement(vector<int>& nums) {
        return majorityElement(nums, 3);
    }
};

这种做法中map的存储数据大小是3个,所以可以认为是constant space。

参考资料:

【1】Moore’s voting algorithm: http://www.cs.utexas.edu/~moore/best-ideas/mjrty/
【2】超过半数的数字: http://blog.csdn.net/chfe007/article/details/42919017

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值