LeetCode300 最长递增子序列
题目
解题
解题一:动态规划
// javascript
var lengthOfLIS = function(nums) {
const len = nums.length;
if (len === 0) return 0;
const dp = new Array(len).fill(1);
let maxLen = 1;
for (let i = 1; i < len; i++) {
for (let j = 0; j < i; j++) {
// 不能加到 for 循环的判断条件上!不然碰到一个 >= 的 循环就结束了啊喂
if (nums[j] < nums[i]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
maxLen = Math.max(maxLen, dp[i]);
}
return maxLen;
};
解题二:贪心 + 二分查找
因为记录的数组具有 严格递增性,所以可以用二分查找寻找 第一个大于等于 nums[i] 的元素。
// javascript
var lengthOfLIS = function(nums) {
const len = nums.length;
if (len === 0) return 0;
const d = new Array(len + 1).fill(0);
let maxLen = 1;
d[maxLen] = nums[0];
for (let i = 1; i < len; i++) {
if (nums[i] > d[maxLen]) {
d[++maxLen] = nums[i];
} else {
let left = 1, right = maxLen; // 注意是从 1 到 maxLen 范围内寻找
while (left <= right) {
const mid = left + ((right - left) >> 1);
if (d[mid] < nums[i]) left = mid + 1;
else right = mid - 1;
}
d[left] = nums[i];
}
}
return maxLen;
};
二分查找的部分也可以写成如下这种形式:
// javascript
var lengthOfLIS = function(nums) {
const len = nums.length;
if (len === 0) return 0;
const d = new Array(len + 1).fill(0);
let maxLen = 1;
d[maxLen] = nums[0];
for (let i = 1; i < len; i++) {
if (nums[i] > d[maxLen]) {
d[++maxLen] = nums[i];
} else {
let left = 1, right = maxLen + 1;
while (left < right) {
const mid = left + ((right - left) >> 1);
if (d[mid] < nums[i]) left = mid + 1;
else right = mid;
}
d[left] = nums[i];
}
}
return maxLen;
};