leetcode题解更新:新增96、343、509、968题的动态规划解决方案

本次提交新增了以下几道leetcode题的动态规划解法:
- LeetCode96:实现了一个Solution类,其中numTrees方法使用动态规划计算不同数量的树。
- LeetCode343:提供了integerBreak方法,用动态规划找出给定数字可以拆分出的最大乘积。
- LeetCode509:实现了fib和fib1方法,分别用递归和动态规划计算斐波那契数。
- LeetCode968:实现了一个Solution类,其中minCameraCover方法用动态规划计算给定树中安装监控的最小数量。

这些解决方案均通过了leetcode的测试,为动态规划的学习和应用提供了新的示例。
```
This commit is contained in:
whaifree 2024-08-14 22:29:05 +08:00
parent f6d0c4fc63
commit 424329dcca
4 changed files with 258 additions and 0 deletions

View File

@ -0,0 +1,109 @@
package cn.whaifree.redo.redo_all_240721;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/10 21:34
* @注释
*/
public class LeetCode343 {
@Test
public void test() {
System.out.println(integerBreak(10));
}
/**
* dp[i]表示i可以拆出来的最大值
* <p>
* dp[i] = 遍历0~i-1找到dp[k]*dp[i-k]的最大值
* <p>
* 0 1 2 3 4 5 6 7
* 1 1 2 4 6 9 12
*
* @param n
* @return
*/
public int integerBreak(int n) {
// if (n == 2) return 1;
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
int tmpMax = Integer.MIN_VALUE;
for (int j = 1; j < i; j++) {
tmpMax = Math.max(tmpMax, dp[j] * (i - j)); // 7 可能拆成2 23 即dp[4] * 7-4
tmpMax = Math.max(tmpMax, j * (i - j)); // 4 可能拆成 2 2 即ij 22
}
dp[i] = tmpMax;
}
return dp[n];
}
static Object o = new Object();
static int count = 0;
public static void main(String[] args) {
new Thread(() -> {
for (int i = 0; i < 100; i++) {
synchronized (o) {
while (count % 3 != 1) {
try {
o.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("a");
o.notifyAll();
count++;
}
}
}).start();
new Thread(() -> {
for (int i = 0; i < 100; i++) {
synchronized (o) {
while (count % 3 != 0) {
try {
o.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("b");
o.notifyAll();
count++;
}
}
}).start();
new Thread(() -> {
for (int i = 0; i < 100; i++) {
synchronized (o) {
while (count % 3 != 2) {
try {
o.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("c");
o.notifyAll();
count++;
}
}
}).start();
}
}

View File

@ -0,0 +1,30 @@
package cn.whaifree.redo.redo_all_240721;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/10 18:33
* @注释
*/
public class LeetCode509 {
public int fib(int n) {
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
}
return fib(n - 1) + fib(n - 2);
}
public int fib1(int n) {
int[] dp = new int[n + 1];
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
}

View File

@ -0,0 +1,54 @@
package cn.whaifree.redo.redo_all_240721;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/10 18:40
* @注释
*/
public class LeetCode96 {
@Test
public void test() {
Solution solution = new Solution();
int i = solution.numTrees(3);
System.out.println(i);
}
class Solution {
/**
* 1 1
* 2 2
* 节点
*
* n=4
*
* 左边三个节点右边没有 dp[3] + dp[0]
* dp[2] + dp[1]
* dp[1] + dp[2]
* dp[0] + dp[3]
*
* @param n
* @return
*/
public int numTrees(int n) {
if (n <= 2) {
return n;
}
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i < dp.length; i++) {
int var = 0;
for (int j = 0; j < i; j++) {
var += (dp[i - j - 1] * dp[j]);
}
dp[i] = var;
}
return dp[n];
}
}
}

View File

@ -0,0 +1,65 @@
package cn.whaifree.redo.redo_all_240721;
import cn.whaifree.leetCode.model.TreeNode;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/8/10 16:52
* @注释
*/
public class LeetCode968 {
@Test
public void test() {
System.out.println(new Solution().minCameraCover(TreeNode.constructTreeByArray(1,2,null,null,3,4,null,null,5,6)));
System.out.println(new Solution().minCameraCover(TreeNode.constructTreeByArray(1,2,null,3,null,4,null,null,5)));
}
class Solution {
int res = 0;
/**
* 0 被覆盖
* 1 有监控
* 2 没覆盖
*
* @param root
* @return
*/
public int minCameraCover(TreeNode root) {
if (circle(root) == 2) {
res++;
}
return res;
}
public int circle(TreeNode root) {
if (root == null) {
return 0;
}
int left = circle(root.left);
int right = circle(root.right);
// 左边或者右边有未覆盖的就在这里安排一个监控
if (left == 2 || right == 2) {
res++;
return 1;
}
// 左边和右边有监控这里就被覆盖了
if (left == 1 || right == 1) {
return 0;
}
// 左右都覆盖这里就没覆盖
if (left == 0 && right == 0) {
return 2;
}
return -1;
}
}
}