当前位置: 首页 > news >正文

最长递增子序列问题(LIS) 动态规划 JavaScript

Overlapping Subproblems 重叠子问题

Optimal Substructure 最优子结构

unweighted graph 无权图,在图论中出现。

Longest Increasing Subsequence (LIS)最长上升子序列

exponential 指数的 呈指数

最长递增子序列问题(LIS) 动态规划 JavaScript

问题很简单,给定一个数组,找出这个数组的最长递增子序列,返回其长度。

分析:

在分析中,你需要对子序列、最长递增子序列、当前最长递增子序列加以区分,以免混淆。
分析中的变量:

  • nums - 给定的数组
  • n - 给定数组的长度
  • lis[i] - nums.slice(0, i)的最长递增子序列长度

事实A:一个递增子序列长度增加,一定是新元素比当前最长递增子序列中的(最后一个)元素大。有新元素添加到最长递增子序列中后,当前最长递增子序列的长度增加1 。

根据事实A可得 如果存在一个j, nums[n] > nums[j],且lis[n] < lis[j] + 1, 则lis[n] = lis[j] + 1
这里会和我们习惯的线性思维有些冲突:我们不是在求解lis[n]吗? lis[n] < lis[j] + 1 这个如何判断呢?这个就是DP中D的作用,问题的解是在动态变化的,lis[n]的值也在不断变化,直到找到正解。

因此,我们需要找到所有 0 < j < n 中,满足上述条件的最优j。由求lis[n]的过程可得,求lis[n-1]也类似,去寻找满足 0 < j < n - 1 的最优j。这种自上而下的动态求解,称为Memoization 记忆法。而重复寻找最优的j的过程,则是寻找 Optimal Substructure 最优子结构的过程。
在这里插入图片描述

代码实现:

var lengthOfLIS = function(nums) {

    var max = 0
    var lis = new Array(nums.length)
    
    for(let i = 0; i < nums.length; i++) {
        lis[i] = 1
    }
    
    for (let i = 0; i < nums.length; i++) {
        for (let j = 0; j < i; j++) {
            if (nums[i] > nums[j] && lis[j] + 1 > lis[i]) {
                lis[i] = lis[j] + 1
            }
        }
    }

    for (let i = 0; i < nums.length; i++) {
        if (max < lis[i]) {
            max = lis[i]
        }
    }

    return max
};

如果你有任何疑问,请留言,我会尽力为你解答。

相关文章:

  • 位屏蔽(Bitmasking)中屏蔽字赋值语句 mask | (1 << j) 的解释
  • 【Java to Architect】synchronized保证内存可见性 demo的另一种解法
  • 利用位屏蔽和动态规划解决最小代价任务分配问题 Bitmasking Dynamic Programming
  • 算法:回溯法(backtracking)解决寻找给定字符串的所有排序(permutations)问题
  • 算法: 动态规划 寻找2D矩阵中到达某一坐标的最小代价路径
  • 算法:动态规划 寻找2D矩阵中到达某一坐标的可能路径总数
  • 算法:动态规划 寻找2D矩阵中到达某一坐标的可能路径总数进阶版(添加路障)
  • 算法: 动态规划,二维矩阵代价最值进阶版 两条行进路径,一次相交,求解最大代价
  • Programming Languages And Lambda calculi 1.1 定义集合
  • 算法: 动态规划 编辑距离 Edit Distance / Levenshtein Distance
  • 【Salesforce】【Apex】Trigger中不通过soql查询记录类型的开发名称
  • 【Programming Languages And Lambda calculi】 1.2 ~ 1.3 关系、赋值与关系
  • 【Programming Languages And Lambda calculi】 1.4 有向赋值
  • 【算法】 动态规划 基础题库 1-7 python实现
  • 【Programming Languages And Lambda calculi】 1.5 ~ 1.7 上下文规约 赋值函数 符号摘要
  • classpath对获取配置文件的影响
  • HTTP 简介
  • Java 多线程编程之:notify 和 wait 用法
  • Java到底能干嘛?
  • Map集合、散列表、红黑树介绍
  • MySQL的数据类型
  • passportjs 源码分析
  • PHP 小技巧
  • React中的“虫洞”——Context
  • Spring声明式事务管理之一:五大属性分析
  • 半理解系列--Promise的进化史
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 二维平面内的碰撞检测【一】
  • 工作手记之html2canvas使用概述
  • 记一次删除Git记录中的大文件的过程
  • 每天10道Java面试题,跟我走,offer有!
  • 你真的知道 == 和 equals 的区别吗?
  • 收藏好这篇,别再只说“数据劫持”了
  • (C)一些题4
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (蓝桥杯每日一题)love
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (四)【Jmeter】 JMeter的界面布局与组件概述
  • (一一四)第九章编程练习
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)3D模板阴影原理
  • (转)Mysql的优化设置
  • .bat批处理出现中文乱码的情况
  • .FileZilla的使用和主动模式被动模式介绍
  • .gitattributes 文件
  • .NET Standard / dotnet-core / net472 —— .NET 究竟应该如何大小写?
  • .net 开发怎么实现前后端分离_前后端分离:分离式开发和一体式发布
  • .net 无限分类
  • .Net 应用中使用dot trace进行性能诊断
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • /deep/和 >>>以及 ::v-deep 三者的区别
  • /etc/X11/xorg.conf 文件被误改后进不了图形化界面
  • [Android Pro] Notification的使用
  • [BUG] Hadoop-3.3.4集群yarn管理页面子队列不显示任务