Longest Consecutive Sequence
Given an unsorted array of integers, find the length of the longest consecutive elements sequence.
For example,
Given [100, 4, 200, 1, 3, 2]
,
The longest consecutive elements sequence is [1, 2, 3, 4]
. Return its length: 4
.
Your algorithm should run in O(n) complexity.
int longestConsecutive(vector<int>& nums) {
int maxLen = 0;
unordered_set<int> s(nums.begin(), nums.end()); //普通set的查找是logn的,unordered_set是O(1)
while(!s.empty()){
int num = *(s.begin());
s.erase(num);
int right = num + 1;
while(s.find(right) != s.end()) s.erase(right++);
int left = num - 1;
while(s.find(left) != s.end()) s.erase(left--);
maxLen = max(maxLen, right - left - 1);
}
return maxLen;
}
Given an unsorted integer array, find the first missing positive integer.
For example,
Given [1,2,0]
return 3
,
and [3,4,-1,1]
return 2
.
Your algorithm should run in O(n) time and uses constant space.
首先一点,如果数组中有k个正数,那么first missing positive 一定在[1, k+1]区间里。因此,我们把所有的正数放在数组中正确的位置(把nums[i]放在数组的nums[i] - 1位置);之后重新遍历数组,遇到的第一个value != i + 1的数,即为first missing positve. int firstMissingPositive(vector<int>& nums) {
for(int i = 0; i < nums.size(); i++){
while(nums[i] > 0 && nums[i] <= nums.size() && nums[nums[i]-1] != nums[i]){
swap(nums[i], nums[nums[i]-1]);
}
}
for(int i = 0; i < nums.size(); i++){
if(nums[i] != i+1) return i+1;
}
return nums.size() + 1;
}
Best Time to Buy and Sell Stock III
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most two transactions
四个变量代表该交易之后的余额,buy1st代表第一次买之后的余额。DP问题要找到状态和状态之间的转移方程。在该问题中,每次交易都会影响下一次交易的利润。所以状态应该是每次在某个价格进行buy和sell交易。
int maxProfit(vector<int>& prices) {
int buy1st = INT_MIN, sold1st = 0;
int buy2nd = INT_MIN, sold2nd = 0;
for(int i = 0; i < prices.size(); i++){
sold2nd = max(sold2nd, buy2nd + prices[i]);
buy2nd = max(buy2nd, sold1st - prices[i]);
sold1st = max(sold1st, buy1st + prices[i]);
buy1st = max(buy1st, -prices[i]);
}
return sold2nd;
}
推广至at most K transaction的DP解法,at most K transaction 被 at most K-1 transaction的盈利情况影响。上述第一种解法将情况进行了更细致的刻画,在一趟扫描中同时记录K 和 K-1次的交易后的情况。
int maxProfit(vector<int> &prices) {
// f[k, ii] represents the max profit up until prices[ii] (Note: NOT ending with prices[ii]) using at most k transactions.
// f[k, ii] = max(f[k, ii-1], prices[ii] - prices[jj] + f[k-1, jj]) { jj in range of [0, ii-1] }
// = max(f[k, ii-1], prices[ii] + max(f[k-1, jj] - prices[jj]))
// f[0, ii] = 0; 0 times transation makes 0 profit
// f[k, 0] = 0; if there is only one price data point you can't make any money no matter how many times you can trade
if (prices.size() <= 1) return 0;
else {
int K = 2; // number of max transation allowed
int maxProf = 0;
vector<vector<int>> f(K+1, vector<int>(prices.size(), 0));
for (int kk = 1; kk <= K; kk++) {
int tmpMax = f[kk-1][0] - prices[0];
for (int ii = 1; ii < prices.size(); ii++) {
f[kk][ii] = max(f[kk][ii-1], prices[ii] + tmpMax);
tmpMax = max(tmpMax, f[kk-1][ii] - prices[ii]);
maxProf = max(f[kk][ii], maxProf);
}
}
return maxProf;
}
}
Find Minimum in Rotated Sorted Array II
Follow up for "Find Minimum in Rotated Sorted Array":
What if duplicates are allowed?
(i.e., 0 1 2 4 5 6 7
might become 4 5 6 7 0 1 2
).
Find number in rotated sorted array的简化版,但存在重复数字时,两端相等时无法确定half与minumum的大小(即无法通过half确定minimum的位置),只能 right-- 逐个移动。
int findMin(vector<int>& nums) {
int left = 0, right = nums.size() - 1;
int half = 0;
while(left < right){
half = (left+right) / 2;
if(nums[half] < nums[right]) right = half;
else if(nums[half] == nums[right]) right--;
else left = half + 1;
}
return nums[left];
}