代码随想录 300.最长递增子序列
思路根据题意得子序列是由数组派生而来的序列删除或不删除数组中的元素不改变其余元素的顺序。动规五部曲1.dp[i]的定义dp[i]表示i之前包括i的以nums[i]结尾的最长递增子序列的长度。2.确定递推公式状态转移方程1位置i的最长递增子序列等于j从0到i - 1各个位置的最长递增子序列 1的最大值。2所以if(nums[i] nums[j]) dp[i] max(dp[i],dp[j] 1)。这里不是将dp[i]与dp[j] 1比较而是选取dp[j] 1的最大值。3.dp[i]的初始化每一个i对应的dp[i]即最长递增子序列起始大小至少都是1。4.确定遍历顺序1dp[i]是由0到i - 1各个位置的最长递增子序列推导而来因此遍历i一定是从前向后遍历。2j就是遍历0到i - 1因此从前到后或从后到前的遍历顺序都无所谓只要把0到i - 1的元素都遍历到就行。默认习惯为从前到后遍历。遍历i的循环在外层遍历j的循环在内层代码如下所示for (int i 1; i nums.size(); i) { for (int j 0; j i; j) { if (nums[i] nums[j]) dp[i] max(dp[i], dp[j] 1); } if (dp[i] result) result dp[i]; // 取长的子序列 }5.举例推导dp数组输入[0,1,0,3,2],dp数组的变化如下所示。注意子序列和子数组的区别和计算方式1子序列位置可以不连续因此可能性更多且是外层for i内层for j代表所有的可能性。2子数组位置必须连续因此是单层for循环即可代表所有的可能性且子数组问题考虑的子数组必须以nums[i]结尾。附代码class Solution { public int lengthOfLIS(int[] nums) { if(nums.length 1){ return nums.length; } int res 1; int[] dp new int[nums.length]; for(int i 0;i nums.length;i){ dp[i] 1; } for(int i 1;i nums.length;i){ for(int j 0;j i;j){ if(nums[i] nums[j]){ dp[i] Math.max(dp[i],dp[j] 1); } } res Math.max(res,dp[i]); } return res; } }
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2476601.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!