64.最长递增子序列

130 阅读2分钟

day14: 300. 最长递增子序列 (中等)

考点:动态规划

动态规划思想: 在每个阶段都求得一个最优解,以此来达到结果最优的效果。 将每个问题分解成若干个子问题,先求解子问题,然后从子问题中得到原问题的解。 我们保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。

过程分析:

  • 用一个dp来存储每一步得到的结果,初始化可以都为1。可以这么理解,假使当前元素为10,在10 前面没有任何一个元素比10 小,因此可以认为以10 开始的最长子序列长度为1,即只有其自身。
  • 假使当前元素为9,在9前面没有任何一个元素比9小,因此可以认为以9 开始的最长子序列长度为1,即只有其自身.
  • 假使当前元素为2,在9前面没有任何一个元素比2小,因此可以认为以2 开始的最长子序列长度为1,即只有其自身.
  • 假使当前元素为5,在5前面存在1个元素2比5小,因此可以认为以5 开始的最长子序列长度为2,即其自身和2.以此类推,可以推出最终的dp为[1, 1, 1, 2, 2, 3, 4, 4] 依旧看不懂的看 -> :这里
var lengthOfLIS = function(nums) {

 let dp = new Array(nums.length).fill(1),
    max = 1;
  for (let i = 1; i < nums.length; i++) {
    for (let j = 0; j < i; j++) {
      if (nums[i] > nums[j]) {
        //dp[j]即为当前元素和其前面元素相比过程中,比其大的元素的长度,求出最大值
        dp[i] = Math.max(dp[i], dp[j] + 1);
      }
    }
//在求出的子集中查找最大值
    max = Math.max(max, dp[i]);
  }
  return max;
};

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