【LeetCode】334#遞增的三元子序列
阿新 • • 發佈:2019-01-08
復雜 時間復雜度 一個 暴力破解 pub 對數 體會 表示 分享圖片
。
題目描述
給定一個未排序的數組,判斷這個數組中是否存在長度為 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、暴力破解
使用三層循環,先找到二元上升序列,再在二元上升序列的基礎上,找三元上升序列,時間復雜度為O(N^3)
源代碼
public boolean increasingTriplet (int[] nums) { if (nums.length < 3) return false; for (int i = 0; i < nums.length-2; i++) { for (int j = i+1; j < nums.length - 1; j++) { if (nums[j] > nums[i]) { for (int k = j+1; k < nums.length; k++) { if (nums[k] > nums[j]) { return true; } } } } } return false; }
2、一次遍歷法
維護兩個常量:min
和second_min
,對數組進行遍歷。
其中,min
表示遍歷到當前位置最小的元素,second_min
表示從min
的位置開始一直到當前位置的第二小元素(也就是比min
大的元素中最小的那一個)。
確定這兩個元素後,再在後續的元素中找有沒有比second_min
大的元素,如果有,就表示存在遞增的三元子序列。
這樣只需要遍歷一次數組,時間復雜度為O(N)
。
示意圖
源代碼
public boolean increasingTriplet (int[] nums) { int min = Integer.MAX_VALUE; int second_min = Integer.MAX_VALUE; for (int num : nums) { if (num<=min) min = num; else if (num < second_min) second_min = num; else if (num > second_min) return true; } return false; }
心得體會
一次遍歷法的巧妙就在於設置了兩個變量(或者叫指針)來保存遞增二元子序列,並實時更新,避免了許多重復的判斷。
【LeetCode】334#遞增的三元子序列