关于vue.js中的最长递增子序列方法

本文分步分析最长递增子序列的求法,解析的是vue中的getSetuence函数,以下是具体过程

找出递增序列

首先找到当前的单调递增序列,设置一个result数组,判断新加入的元素是否比当前最后一个元素大,是的话就push到result中来,得出来一个递增序列1,4,8,但此时的序列并非最长序列,最长序列应为1,4,6,7

js 复制代码
 function a(arr){
       let result = [0]
       for(let i = 0;i<arr.length;i++){
        let arrI = arr[i]
        let resultLast = result[result.length-1]
        if(arrI > arr[resultLast]){
            result.push(i)
        }
       return result.map(item=>arr[item])
    }
    let arr = [1,4,8,3,6,2,7]
    console.log(a(arr));//[1,4,8]

找出最长递增子序列长度

接下来参考力扣300的解法,我们先设法找出最长递增子序列的长度

每次遍历时如果取出的值没有result最后一个值大,那么就找到数组中比当前值大的最小数值并替换之

如下

遍历到2时

数组对应的值 【1、4、8】此时1为数组中比2小的最大值,则数组改为【1、2、8】

同理下次循环后为【1、3、8】

以此类推【1、3、6】、【1、2、6】、【1、2、6、7】

其最长递归子序列的长度则为4,需要注意的是【1、2、6、7】并非所求数组的最长递增子序列,其排序已不是原数组的排序顺序,这点在最后会解决,现在来实现上述过程

js 复制代码
 function a(arr){
       let result = [0]
       for(let i = 0;i<arr.length;i++){
        let arrI = arr[i]
        let resultLast = result[result.length-1]
        if(arrI > arr[resultLast]){
            result.push(i)
            continue
        }
        // 二分法查找比当前值大的最小值   
        let start = 0,end = result.length-1,middle = Math.floor(start - (start-end)/2)
        while(start < end){
            middle = Math.floor(start - (start-end)/2)
            if(arrI <= arr[result[middle]]){
                end = middle
            }else{
                start = middle+1
            }
        }
        // 此时start===end
        result[end] = i

       }
       return result.map(item=>arr[item])
    }
    let arr = [1,4,8,3,6,2,7]
    console.log(a(arr));//【1、2、6、7】

纠正

经过上述两个步骤之后,我们会发现虽然排出了序列,但是显而易见,这个排序是有问题,问题在于我们每次比较完成之后就将后面的值插入到了前面,导致混乱

我们的解决方法是利用一个数组,记录下当前位置的前一个排序位置,从而使得我们可以往前找到我们需要的值

代码如下

js 复制代码
 function a(arr){
     	// 添加数组p进行记录
       let result = [0],p=arr.slice()
       for(let i = 0;i<arr.length;i++){
        let arrI = arr[i]
        let resultLast = result[result.length-1]
        if(arrI > arr[resultLast]){
            result.push(i)
            // 在当前位置记录前一个的索引
            p[i] = resultLast
            continue
        }
        let start = 0,end = result.length-1,middle = Math.floor(start - (start-end)/2)
        while(start < end){
            middle = Math.floor(start - (start-end)/2)
            if(arrI <= arr[result[middle]]){
                end = middle
            }else{
                start = middle+1
            }
        }
        result[end] = i
        // 这里也需要同步记录
        p[i] = result[end-1]
       }
     	// 对数据进行纠正
       let n = result.length,last = result[n-1]
       while(n-- > 0){
        result[n] = last
        last = p[last]
       }
       return result.map(item=>arr[item])
    }
    let arr = [1,4,8,3,6,2,7]
    console.log(a(arr));//[1, 3, 6, 7]
相关推荐
lpfasd1236 小时前
node-sass 停止维护!老项目迁移 Dart Sass 完整教程
前端·rust·sass
Data analyse4568 小时前
rnweb 回放数据量太大怎么办?分片存储与断点续传的实现思路
前端·网络·算法·数据分析
xiaogai_gai8 小时前
金蝶收料通知单查询策略实战教程:从源系统拉取到中间层落地的完整路径
java·前端·数据库
环境栈笔记9 小时前
指纹浏览器 WebRTC 怎么设置?从 ICE 候选、代理出口到功能验证
前端·人工智能·后端·自动化
赵大仁9 小时前
官网性能优化实战:LCP 3.2s → 2.1s、CLS 0.107 → 0,以及被我推翻的 6 个判断
前端·性能优化·cls·lcp·core web vitals
xiancai_xianyu10 小时前
Text2SQL落地生产库前,SQL要过哪三道闸
前端·数据库·sql·sql注入·text2sql·ai agent开发·企业级ai框架
小羊没烦恼!10 小时前
T-SQL查询进阶--理解SQL SERVER中的分区表
服务器·开发语言·前端·javascript·html
史瓦辛格10 小时前
给 DeepSeek Harness 写费用插件:把「这次会话花了多少钱」算准
前端·deepseek
星光不问赶路人10 小时前
Vue 3 + TypeScript 中 enum 的使用实践
前端·vue.js
鸥梨菌Honevid10 小时前
UVM 中 REQ 和 RSP 类型详解:从通信模型到 item_done 与 put_response
java·前端·servlet