1. 程式人生 > >Leetcode:334. 遞增的三元子序列

Leetcode:334. 遞增的三元子序列

給定一個未排序的陣列,判斷這個陣列中是否存在長度為 3 的遞增子序列。

數學表示式如下:

如果存在這樣的  i, j, k,  且滿足 0 ≤  i <  j <  k ≤  n-1,
使得  arr[i] <  arr[j] <  arr[k] ,返回 true ; 否則返回 false 。

說明: 要求演算法的時間複雜度為 O(n

),空間複雜度為 O(1) 。

示例 1:

輸入: [1,2,3,4,5]
輸出: true

示例 2:

輸入: [5,4,3,2,1]
輸出: false

解題思路:

邏輯題。

  1. 找到一個遞增數num[pos],例如,[5,4,3,4,5,6,]中第4個數4就是第一個遞增數。
  2. 第一個遞增數的前面必然是當前遇到的最小數。如果不是那麼nums[pos-1]才是第一個遞增數。如果連遞增數都沒有,就不可能有三連遞增。
  3. 這裡我們確定了二元遞增的兩個數,nums[left],nums[right],其中left=pos-1,right=pos。以及最小數的位置temp,一開始nums[temp]=nums[pos-1]。
  4. 隨後接著訪問pos+1,nums[pos+1]需要根據數值de得大小分類處理。
  • nums[pos+1]>nums[right],那麼找到了三元序列。
  • nums[pos+1]>nums[left]&&nums[pos+1]<=nums[right]。修改二元序列得右值,right = pos+1;
  • nums[pos+1]<=nums[temp]。修改位於left之後最小數得位置。temp=pos+1。
  • nums[pos+1]>nums[temp]&&nums[pos+1]<=nums[left],說明,發現了位置跟後,數值更小得得二元序列,二元序列需要改變位置。left = temp,right=pos+1。

重複上述步驟直到訪問所有元素。

C++程式碼
class Solution {
public:
    bool increasingTriplet(vector<int>& nums) {
        int size = nums.size();
        //找到第一個升序
        int i = 0, pos = -1, min = INT_MAX;
        while (i < size-1) {
            if (nums[i] < nums[i + 1]) { pos = i; break; }
            min = (nums[i] < min ? nums[i] : min);
            i++;
        }
        if (pos == -1) return false;
        int left = i, right = i + 1;
        pos = right + 1;
        int temp = left;
        while (pos < size) {
            if (nums[pos]>nums[right]) return true;
            if (nums[pos] <= nums[temp]) temp = pos;
            if (nums[pos] > nums[temp] && nums[pos] <= nums[left]) { left = temp; right = pos; }
            if (nums[pos] >nums[left] && nums[pos] <= nums[right]) right = pos;
            pos++;
        }
        return false;
    }
};