Array(12) -- Longest Consecutive Sequence, First Missing Positive, Buy and Sell Stock III, Find Mini

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.


将vector转成set,任取set中的一个元素,分别向左右两边寻找序列,并不断删除已查找过的元素,直到set为空。

    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;
    }



First Missing Positive

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];
    }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值