提交动态规划相关问题解决方案:不相交线、最大子序列和、子序列判断。

This commit is contained in:
whaifree 2024-04-25 13:16:43 +08:00
parent e20cf9cea7
commit 6bddb836c9
3 changed files with 190 additions and 0 deletions

View File

@ -0,0 +1,61 @@
package cn.whaifree.leetCode.Dynamic;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/25 11:28
* @注释
*/
public class LeetCode1035 {
@Test
public void test()
{
int[] nums1 = new int[]{1,3,7,1,7,5};
int[] nums2 = new int[]{1,9,2,5,1};
System.out.println(new Solution().maxUncrossedLines(nums1, nums2));
}
class Solution {
/**
* 不相交就是挨个求nums1的子序列在nums中出现的次数
* - 不用连续
* - 子序列
*
* dp[i][j] 表示 nums1从0-i-1nums2从0-j-1有几个相同的子序列
*
* if nums1[i] == nums2[j]
* dp[i][j] = dp[i-1][j-1]+1
* else
* dp[i][j] = dp[i-1][j-1]
*
*
* @param nums1 短的
* @param nums2 长的
* @return
*/
public int maxUncrossedLines(int[] nums1, int[] nums2) {
if (nums1.length > nums2.length) {
return maxUncrossedLines(nums2, nums1);
}
int[][] dp = new int[nums1.length + 1][nums2.length + 1];
for (int i = 1; i <= nums1.length; i++) {
for (int j = 1; j <= nums2.length; j++) {
if (nums1[i - 1] == nums2[j - 1]) {
// 对应位置相等则从i-1 j-1的值+1
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
// 对应的值不相等则获取前面已经匹配的最大值
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[nums1.length][nums2.length];
}
}
}

View File

@ -0,0 +1,82 @@
package cn.whaifree.leetCode.Dynamic;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/25 12:41
* @注释
*/
public class LeetCode392 {
@Test
public void test() {
String s = "abc";
String t = "ahbgdc";
boolean subsequence = new Solution1().isSubsequence(s, t);
System.out.println(subsequence);
}
class Solution {
/**
* 子序列
* s是否是t的子序列
*
* dp[i][j] 表示
*
* @param s
* @param t
* @return
*/
public boolean isSubsequence(String s, String t) {
boolean flag = false;
int j = 0;
for (int i = 0; i < s.length(); i++) {
while (j < t.length()) {
if (s.charAt(i) == t.charAt(j)) {
flag = true;
j++;
break;
}
j++;
}
if (!flag) {
return false;
}
flag = false;
}
return true;
}
}
class Solution1 {
/**
* dp[i][j]表示s的i到t的j 相同子序列的长度
*
* 转变为 求两个序列相同子序列的长度
*
* ahbgdc
* acbdc
* @param s
* @param t
* @return
*/
public boolean isSubsequence(String s, String t) {
int[][] dp = new int[s.length() + 1][t.length() + 1];
char[] s1 = s.toCharArray();
char[] t1 = t.toCharArray();
for (int i = 1; i <= s1.length; i++) {
for (int j = 1; j <= t1.length; j++) {
if (s1[i - 1] == t1[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]);
}
}
}
return dp[s1.length][t1.length] == s1.length;
}
}
}

View File

@ -0,0 +1,47 @@
package cn.whaifree.leetCode.Dynamic;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/25 11:59
* @注释
*/
public class LeetCode53 {
@Test
public void test() {
Solution solution = new Solution();
int[] nums = new int[]{-1,-3};
int i = solution.maxSubArray(nums);
System.out.println(i);
}
class Solution {
/**
*
* @param nums
* @return
*/
public int maxSubArray(int[] nums) {
// dp[i] 表示包含元素i的的最大和
// dp[0] = nums[0]
int[] dp = new int[nums.length];
dp[0] = nums[0];
int max = nums[0];
for (int i = 1; i < nums.length; i++) {
if (dp[i - 1] > 0 && dp[i - 1] + nums[i] > 0) { // 如果p[i - 1] < 0 则只能拖后腿
dp[i] = dp[i - 1] + nums[i];
} else {
// 拖后腿重新计算
dp[i] = nums[i];
}
max = Math.max(max, dp[i]);
}
return max;
}
}
}