longest increasing subsequence 300, 354
Given an integer array nums, return the length of the longest strictly increasing subsequence.
A subsequence is a sequence that can be derived from an array by deleting some or no elements without changing the order of the remaining elements. For example, [3,6,2,7] is a subsequence of the array [0,3,1,6,2,2,7].
Example 1:
Input: nums = [10,9,2,5,3,7,101,18] Output: 4 Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4.
Example 2:
Input: nums = [0,1,0,3,2,3] Output: 4
Example 3:
Input: nums = [7,7,7,7,7,7,7] Output: 1
Constraints:
1 <= nums.length <= 2500-104 <= nums[i] <= 104
Follow up: Can you come up with an algorithm that runs in O(n log(n)) time complexity?
解法1:
class Solution { public int lengthOfLIS(int[] nums) { int[] dp = new int[nums.length]; int result = 1; Arrays.fill(dp, 1); for(int i=0;i<nums.length-1;i++){ for(int j=i+1;j<nums.length;j++){
// 如果跟前一元素递增,那么尝试用前一元素的结果+1 if(nums[i] < nums[j]) dp[j] = Math.max(dp[j], dp[i]+1); result = Math.max(result, dp[j]); } } return result; } }
时间复杂度: O(N2)
解法2:
维护单调递增的序列,二分查找,在找到的位置进行替换
class Solution { public int lengthOfLIS(int[] nums) { List<Integer> list = new ArrayList(); for(int i=0;i<nums.length;i++){ int pos = binarySearch(list, nums[i]); if(pos >= list.size()) list.add(nums[i]); else list.set(pos, nums[i]); } return list.size(); } private int binarySearch(List<Integer> list, int target){ int left = 0,right = list.size(); while(left < right){ int mid = left+(right-left)/2; if(list.get(mid) >= target) right = mid; else left = mid+1; } return left; } }
时间复杂度:O(NlogN)
You are given a 2D array of integers envelopes where envelopes[i] = [wi, hi] represents the width and the height of an envelope.
One envelope can fit into another if and only if both the width and height of one envelope are greater than the other envelope's width and height.
Return the maximum number of envelopes you can Russian doll (i.e., put one inside the other).
Note: You cannot rotate an envelope.
Example 1:
Input: envelopes = [[5,4],[6,4],[6,7],[2,3]]
Output: 3
Explanation: The maximum number of envelopes you can Russian doll is 3 ([2,3] => [5,4] => [6,7]).
Example 2:
Input: envelopes = [[1,1],[1,1],[1,1]] Output: 1
Constraints:
1 <= envelopes.length <= 105envelopes[i].length == 21 <= wi, hi <= 105
解法:按照[0]递增进行排序,[0]相同的按照[1]进行递减排序,然后对[1]做longest increasing subsequence 就可以了
为什么要对[1]进行递减排序呢?看这个例子:[5,4],[6,5],[6,7],[2,3] ,如果按照两个字段都是递增排序的话,排序后为:[2,3] [5,4] [6,5] [6,7] ,那么按照[1] 我们得到的lis是4,而不是3,但是实际[6,5]和[6,7]没法套
class Solution { public int maxEnvelopes(int[][] envelopes) { //根据[0]递增[1]递减进行排序 Arrays.sort(envelopes, (x,y)->{ if(x[0]!=y[0]) return x[0]-y[0]; return y[1]-x[1]; }); //然后求[1]的longest increasing subsequence return lis(envelopes); } private int lis(int[][] evlps){ List<Integer> list = new ArrayList(); for(int i=0;i<evlps.length;i++){ int pos = bs(list, evlps[i][1]); if(pos >= list.size()){ list.add(evlps[i][1]); } else{ list.set(pos, evlps[i][1]); } } return list.size(); } private int bs(List<Integer> list, int target){ int left = 0, right = list.size(); while(left < right){ int mid = left+(right-left)/2; if(list.get(mid) < target) left = mid+1; else right = mid; } return left; } }

浙公网安备 33010602011771号