【LeetCode】334. Increasing Triplet Subsequence 递增的三元子序列(Medium)(JAVA)
题目地址: https://leetcode.com/problems/increasing-triplet-subsequence/
题目描述:
Given an integer array nums, return true if there exists a triple of indices (i, j, k) such that i < j < k and nums[i] < nums[j] < nums[k]. If no such indices exists, return false.
Example 1:
Input: nums = [1,2,3,4,5]
Output: true
Explanation: Any triplet where i < j < k is valid.
Example 2:
Input: nums = [5,4,3,2,1]
Output: false
Explanation: No triplet exists.
Example 3:
Input: nums = [2,1,5,0,4,6]
Output: true
Explanation: The triplet (3, 4, 5) is valid because nums[3] == 0 < nums[4] == 4 < nums[5] == 6.
Constraints:
- 1 <= nums.length <= 10^5
- -2^31 <= nums[i] <= 2^31 - 1
Follow up: Could you implement a solution that runs in O(n) time complexity and O(1) space complexity?
题目大意
给定一个未排序的数组,判断这个数组中是否存在长度为 3 的递增子序列。
数学表达式如下:
- 如果存在这样的 i, j, k, 且满足 0 ≤ i < j < k ≤ n-1,
- 使得 arr[i] < arr[j] < arr[k] ,返回 true ; 否则返回 false 。
说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1) 。
解题方法
- 这一题和求连续最长的递增序列类似,这题是那一题的简化,只要其三个数递增即可
- 这里提供了 n 个数递增序列的方法
- 如果当前数比 list 的最后一个数还要大,就把当前数存入 list 里面,list 的长度就是递增序列的最大长度
- 如果比 list 的最后一个数小于等于的话,就把 list 中刚好比当前 num 大的数替换了(这样做是为了下一个可以递增的数可以尽可能的小,也就是前一个数可以尽可能的小)
class Solution {
public boolean increasingTriplet(int[] nums) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
if (insert(list, nums[i], 3)) return true;
}
return false;
}
public boolean insert(List<Integer> list, int num, int max) {
if (list.size() == 0) {
list.add(num);
return false;
}
int last = list.size() - 1;
if (list.get(last) < num) {
list.add(num);
return list.size() >= max;
}
int start = 0;
int end = list.size() - 1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (list.get(mid) == num) {
start = mid;
break;
} else if (list.get(mid) > num) {
end = mid - 1;
} else {
start = mid + 1;
}
}
list.set(start, num);
return false;
}
}
执行耗时:2 ms,击败了17.98% 的Java用户
内存消耗:38 MB,击败了90.25% 的Java用户