「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」
题解: leetcode-最长递增子序列
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
示例:
输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
根据题意首先进行特殊情况的排除:当nums
里仅有一个元素时,直接返回本身
const n = nums.length
if(n<=1) return n
接下来选择解题方法,理清思路:
- 为了查找并记录最长的递增子序列,需要创建一个新的数组
dp
来存放筛选后的数据 - 创建循环,判断比较,将满足最长子序列的数值添加的
dp
中的合适位置
cosnt dp = [null,nums[0]];//新建一个dp数组,第一个存储为null,第二个存储为nums的第一个值
let max = 1;//记录dp数组的最大长度
for(let i = 1; i < n; i++){
//注意:在这里i是从nums的第二个数值开始的,而dp的max为nums为max-1
//先进行初步判断,如果下一个将要添加到dp数值中的值大于max时,直接进行添加操作
//添加完成后,执行continue操作,将i的值加1
if(dp[max] < nums[i]){
dp[++max] = nums[i]; //++max,将nums[i]添加到下一个,并同时改变max的值
continue;
}
//接下来,进行二分法的查找和比较
//----
}
- 从
nums
当中一次取出一个数值,采用二分法与dp
数值中的值进行判断比较,确定添加位置
let pos = 0; //初始化pos,来确定nums[i]将要插入的位置
let left = 1,
right = max,
mid;
//在这里二分法是对dp数组进行操作
while(left <= right){
mid = (left + right) >> 1; //位运算,同理于除以2向下取整
//mid = Math.floor((left + right) / 2);
//判断、比较、记录
if(num[i] > dp[max]){
left = mid + 1;//当dp的下一个nums值较中间的值大时,将left移动到mid的右侧
pos = mid; //pos标记当前的下表位置,nums[i]添加的位置为当前pos的下一个
}else{
right = mid - 1;//当dp的下一个nums值较中间的值小时,将right移动到mid的左侧 当right-1小于left时,说明当前的right和left指向同一个数值
}
}
dp[pos + 1] = nums[i]; //直接进行值替换,二分法分到最后肯定只剩下一种形式:[a] 或 [a,b]
👆 👆 以上就是个人对【最长递增子序列】的代码解法和方法解读。
如果能够解开您的迷惑,不要忘记一键三连哟!!!
完成代码请移步:GitHub(稍后添加)