Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

最长递增子序列 #277

Open
Nasuke opened this issue Nov 5, 2022 · 3 comments
Open

最长递增子序列 #277

Nasuke opened this issue Nov 5, 2022 · 3 comments

Comments

@Nasuke
Copy link
Contributor

Nasuke commented Nov 5, 2022

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。

输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。

参考代码如下:

/**
 * @param {number[]} nums
 * @return {number}
 */
var lengthOfLIS = function(nums) {
    let n = nums.length, res = 0;
    let f = new Array(n).fill(1)

    for(let i = 0; i < n; i++)
        for(let j = 0; j <=i; j++){
            if(nums[j] < nums[i]){
                f[i] = Math.max(f[i], f[j] + 1)
            }
        }
    for(let i = 0; i < n; i++){
        res = Math.max(f[i],res)
    }
    return res
};
@object-kaz
Copy link
Contributor

@xiaodye
Copy link

xiaodye commented Jan 11, 2023

动态规划,dp大法

/**
 * 给定一个无序的整数数组,找到其中最长上升子序列的长度。
 * @param nums
 * @returns
 */
const lengthOfLIS = function (nums: number[]): number {
  if (nums.length === 0) return 0;

  const dp = new Array<number>(nums.length).fill(1);
  let maxLen = 1;

  // 从第2个元素开始,遍历整个数组
  for (let i = 1; i < nums.length; i++) {
    // 每遍历一个新元素,都要“回头看”,看看能不能延长原有的上升子序列
    for (let j = 0; j < i; j++) {
      // 若遇到了一个比当前元素小的值,则意味着遇到了一个可以延长的上升子序列,故更新当前元素索引位对应的状态
      if (nums[j] < nums[i]) {
        dp[i] = Math.max(dp[i], dp[j] + 1);
      }
    }

    if (dp[i] > maxLen) {
      maxLen = dp[i];
    }
  }

  return maxLen;
};

// test
console.log(lengthOfLIS([10, 9, 2, 5, 3, 7, 101, 18]));

@JsweetA
Copy link

JsweetA commented Oct 22, 2023

/**
 * @param {number[]} nums
 * @return {number}
 */
优化查找
思路:维护一个队列,该队列保持递增。如果新的数比队尾要小,那么在队列里找到第一个比他
 大的并且替换调。
var lengthOfLIS = function (nums) {
    if (nums.length === 0) return 0;
    let res = 0;
    let queue = [], index = 0
    const max = (a, b) => a > b ? a : b;
    // 二分查找:查找出第一个比当前数大或者等于的数
    const check = (queue, val, l, r) => {
        let mid = (l + r) >> 1
        if (l >= r) return r
        if (queue[mid] > val) {
            return check(queue, val, l, mid)
        } else if (queue[mid] < val) {
            return check(queue, val, mid + 1, r)
        } else return mid
    }
    queue[0] = nums[0]
    for (let i = 1; i < nums.length; i++) {
        if (queue[index] < nums[i]) {
            queue[++index] = nums[i]
        }
        else {
            let t = check(queue, nums[i], 0, index);
            queue[t] = nums[i]
        }
        res = max(res, queue.length);
    }
    res = max(res, queue.length);
    return res
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants