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