LeetCode:300. 最长递增子序列 - 力扣(LeetCode)
1.思路
暴力是没有思路的。动规,线性查找每个索引位置所具有的最大递增子序列数值,每个数值位置的初始值都应该为1。且应该考虑数组长度为1时的情况。或者result初始为1。
2.代码实现
class Solution {
public int lengthOfLIS(int[] nums) {
// dp[i] 表示 nums[i] 及之前的数字中的最长子序列为 dp[i] 个
int[] dp = new int[nums.length];
Arrays.fill(dp, 1); // 每个数字都是一个长度,则每个位置的子序列的最小长度为1
int result = 1; // 记录每个数字位置递增子序列的结果值
for (int i = 1; i < nums.length; i++) { // 遍历每个位置
for (int j = 0; j < i; j++) { // 遍历该位置之前的数字
if (nums[i] > nums[j]) { // 统计小于当前元素的数字nums[j]
dp[i] = Math.max(dp[j] + 1, dp[i]); // 在 dp[j] 的基础上 +1, 与当前 dp[i] 进行比较,取两者中的较大值。
}
}
result = Math.max(dp[i], result); // 记录最大的递增子序列的值
}
return result; // 返回结果值
}
}
3.复杂度分析
时间复杂度:O(n^2).
空间复杂度:O(n).
LeetCode:674. 最长连续递增序列 - 力扣(LeetCode)
1.思路
方法一:最初理解错题意了,想成数值连续了。其实只是大小序列是递增的即可。每个位置作为起始位置进行遍历,循环判断获取符合条件的递增子序列的个数,内层for循环结束之后更新最大递增子序列的个数。
方法二:dp[i]表示以i为开始的最大连续子序列的长度。
2.代码实现
// 暴力解法
class Solution {
public int findLengthOfLCIS(int[] nums) {
int maxLen = 0;
for (int i = 0; i < nums.length; i++) {
int len = 1;
for (int j = i + 1; j < nums.length; j++) {
if (nums[j] > nums[j - 1]) {
len++;
} else {
break;
}
}
maxLen = Math.max(maxLen, len);
}
return maxLen;
}
}
// dp[i]以i为开始的最大连续子序列长度
class Solution {
public int findLengthOfLCIS(int[] nums) {
int[] dp = new int[nums.length];
for (int i = 0; i < nums.length; i++) {
dp[i] = 1;
}
// 结果值
int result = 1;
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i + 1] > nums[i]) {
dp[i + 1] = dp[i] + 1;
}
result = result > dp[i + 1] ? result : dp[i + 1];
}
return result;
}
}
// dp[i]以i为末尾位置的最大连续子序列长度
class Solution {
public int findLengthOfLCIS(int[] nums) {
int[] dp = new int[nums.length];
for (int i = 0; i < nums.length; i++) {
dp[i] = 1;
}
// 结果值
int result = 1;
for (int i = 1; i < nums.length; i++) {
if (nums[i] > nums[i - 1]) {
dp[i] = dp[i - 1] + 1;
}
result = result > dp[i] ? result : dp[i];
}
return result;
}
}
3.复杂度分析
时间复杂度:O(n).
空间复杂度:O(n).
LeetCode:718. 最长重复子数组 - 力扣(LeetCode)
1.思路
dp[i][j]表示i-1,j-1为结尾的两数组的公共子数组的长度。
2.代码实现
// 暴力
class Solution {
public int findLength(int[] nums1, int[] nums2) {
int maxLen = 0;
for (int i = 0; i < nums1.length; i++) {
for (int j = 0; j < nums2.length; j++) {
int len = 0; // 当前位置算起的相同子数组的长度
int p = i; // 目的是避免对 i,j 的起始位置有干扰
int q = j;
while (p < nums1.length && q < nums2.length && nums1[p] == nums2[q]) {
len++;
p++;
q++;
}
maxLen = Math.max(maxLen, len);
}
}
return maxLen;
}
}
class Solution {
public int findLength(int[] nums1, int[] nums2) {
int[][] dp = new int[nums1.length + 1][nums2.length + 1];
int result = 0;
for (int i = 1; i <= nums1.length; i++) {
for (int j = 1; j <= nums2.length; j++) {
if (nums1[i - 1] == nums2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
}
result = Math.max(result, dp[i][j]);
}
}
return result;
}
}
3.复杂度分析
时间复杂度:O(n * m).
空间复杂度:O(n).