题目描述
给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
说明:
- 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
- 你算法的时间复杂度应该为 O(n2) 。
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
解题思路
利用动态规划和二分查找解题。
遍历一遍数组,dp[]
表示目前为止的上升子序列(不一定是最长),通过二分查找,找到当前元素在dp[]
中的位置,如果为负值,则说明该元素比dp[]
中所有元素都小,索引值要相应处理一下,然后原地替换;如果为正值,说明该元素比dp[]
中所有元素都大,则加入尾部,顺便len++
。
Java 实现
public int lengthOfLIS (int[] nums) { int[] dp = new int[nums.length]; int len = 0; for (int num : nums) { int i = Arrays.binarySearch(dp,0,len,num); if (i < 0) i = -(i+1); dp[i] = num; if (i == len) len++; } return len;}
心得体会
JDK 中数组二分查找的用法:
public static int binarySearch(int[] a, int fromIndex, int toIndex, int key)Searches a range of the specified array of ints for the specified value using the binary search algorithm. The range must be sorted (as by the method) prior to making this call. If it is not sorted, the results are undefined. If the range contains multiple elements with the specified value, there is no guarantee which one will be found.
- Parameters:
a
- the array to be searched
fromIndex
- the index of the first element (inclusive) to be searched
toIndex
- the index of the last element (exclusive) to be searched
key
- the value to be searched for
- Returns:
index of the search key, if it is contained in the array within the specified range; otherwise,
(-(*insertion point*) - 1)
. The insertion point is defined as the point at which the key would be inserted into the array: the index of the first element in the range greater than the key, ortoIndex
if all elements in the range are less than the specified key. Note that this guarantees that the return value will be >= 0 if and only if the key is found.
- Throws:
IllegalArgumentException
- iffromIndex > toIndex
ArrayIndexOutOfBoundsException
- iffromIndex < 0 or toIndex > a.length
- Since:
1.6