动态规划 背包问题

This commit is contained in:
whai 2024-03-12 19:10:07 +08:00
parent 1eb60f9be4
commit a834a2f158
21 changed files with 1103 additions and 46 deletions

View File

@ -16,7 +16,7 @@ public class LeetCode17 {
@Test @Test
public void test() { public void test() {
String digits = "23"; String digits = "23";
new Solution1().letterCombinations(digits).forEach(s -> System.out.println(s)); new Solution().letterCombinations(digits).forEach(s -> System.out.println(s));
} }
class Solution { class Solution {

View File

@ -0,0 +1,84 @@
package cn.whaifree.leetCode.Dynamic;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/12 16:53
* @注释
*/
public class BeiBao {
@Test
public void main() {
int[] weight = {1,3,4};
int[] value = {15,20,30};
int bagSize = 4;
new Solution().packageProblem(weight, value, bagSize);
}
class Solution{
/**
*
*
* <br/>
* <img src='https://code-thinking-1253855093.file.myqcloud.com/pics/2021011010314055.png' />
*
* @param weights 每个物品的重量
* @param values 每个物品的价值
* @param carryNumber 允许携带的数量
* @return 价值
*/
public int packageProblem(int[] weights, int[] values, int carryNumber) {
/**
* 重量 价值
* 物品0 1 15
* 物品1 3 20
* 物品2 4 30
*/
// dp[i][j] i表示携带的产品j表示容量为j的背包 dp[i][j]为从0-i个产品里取最大的价值
// 1. 不放物品i的最大价值dp[i][j] = dp[i-1][j] 不放物品i所以i不占重量所以不用-weight[i]
// 2. 放物品i的最大价值 dp[i-1][j-weight[i]] + value[i] 如果放了物品i那最大价值就 不放物品i的最大价值+物品i的价值j-weight[i] 表示放i需要腾出来空间
// dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最大价值注意是不放物品i所以要减去weight[i]
// dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); 不放物品的价值 加上i物品的价值
// 初始化如果容量为0最大价值都为0如果容量为123只能放物品0的时候最大价值都是15
int goodsNumber = weights.length;
int[][] dp = new int[goodsNumber][carryNumber + 1];
// 把第0个物品进行初始化前提是能够放入第0个物品
for (int i = weights[0]; i < carryNumber + 1; i++) {
dp[0][i] = values[0];
}
/**
* 先遍历物品再遍历背包
*/
for (int i = 1; i < goodsNumber; i++) {
for (int j = 1; j < carryNumber + 1; j++) {
if (weights[i] > j) {
// 物品i放不进背包容量为j的背包
dp[i][j] = dp[i - 1][j];
}else {
// 能放进去
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weights[i]] + values[i]);
}
}
}
// 打印dp数组
for (int i = 0; i < goodsNumber; i++) {
for (int j = 0; j <= carryNumber; j++) {
System.out.print(dp[i][j] + "\t");
}
System.out.println("\n");
}
return dp[weights.length - 1][carryNumber];
}
}
}

View File

@ -0,0 +1,47 @@
package cn.whaifree.leetCode.Dynamic;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/11 11:14
* @注释
*/
public class LeetCode343 {
@Test
public void test() {
System.out.println(new Solution().integerBreak(10));
}
class Solution {
/**
* dp[i] 表示 拆分出i后的乘积的最大值
* dp[i] = 遍历 dp[i-j] * i 或者 i * j
* dp[i] 可能为两个数相乘或者是多个数相乘这时就需要遍历
* 初始化 dp[0] = nulldp[1] = 1;
*
* [0 1 2 3 4 5 6 7 8 9 10]
* [1 1 1 2 4 6 9 12 16 27 36]
*
*
* @param n
* @return
*/
public int integerBreak(int n) {
int[] dp = new int[n + 1];
// dp[0] = 1;
dp[2] = 1; // 表示数字2可以划分为1+1 1*1为最大值
for (int i = 2; i < n+1; i++) {
for (int j = 1; j < i - 1; j++) {
// Math.max((i - j) * j, dp[i - j] * j) 表示两个数相乘 和使用 前面的数相乘
dp[i] = Math.max(dp[i], Math.max((i - j) * j, dp[i - j] * j));
}
}
return dp[n];
}
}
}

View File

@ -0,0 +1,57 @@
package cn.whaifree.leetCode.Dynamic;
import org.junit.Test;
import java.util.Arrays;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/9 12:04
* @注释
*/
public class LeetCode63 {
@Test
public void test() {
int[][] ints = new int[][]{{0,0,0,0},{0,1,0,0},{0,0,0,0}};
System.out.println(new Solution().uniquePathsWithObstacles(ints));
}
class Solution {
/**
* dp[i][j] 表示 i,j出可能的路径
* dp[i][j] = dp[i-1][j] + dp[i][j-1] 且如果该点有障碍直接continue
* 初始化 dp0,0=0
* @param obstacleGrid
* @return
*/
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
if (obstacleGrid[0][0] == 1) {
return 0;//起点就有障碍不可能过去
}
int h = obstacleGrid.length;
int w = obstacleGrid[0].length;
int[][] dp = new int[h][w];
dp[0][0] = 1;
for (int i = 0; i < dp.length; i++) {
for (int j = 0; j < dp[i].length; j++) {
if (i == 0 && j == 0) {
continue;
}
if (obstacleGrid[i][j] == 0) {
int tmp = 0;
if (i >= 1) tmp += dp[i - 1][j];
if (j >= 1) tmp += dp[i][j - 1];
dp[i][j] = tmp;
}
}
}
return dp[h-1][w-1];
}
}
}

View File

@ -0,0 +1,64 @@
package cn.whaifree.leetCode.Dynamic;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/11 13:08
* @注释
*/
public class LeetCode96 {
@Test
public void test() {
int n = 5;
int result = new Solution().numTrees(n);
System.out.println(result);
}
class Solution {
/**
*
* dp[i] 表示有两个节点的可能数
*
* 以n=3举例二叉搜索树
* 可能的方案
* i表示以i为头节点
* 1. 以1为头结点 右边2个子树+左边0个子树
* 2. 以2为头节点 右边1个子树+左边1个子树
* 3. 以3为头节点 右边0个子树+左边2个子树
*
* dp[3] = 以1为头 dp[2] * dp[0] +
* 以2为头 dp[1] * dp[1] +
* 以3为头 dp[0] * dp[2]
*
* dp[i] = dp[i-1] * dp[0] +
* dp[i-2] * dp[1] +
* dp[i-3] * dp[02] +
* ....
* dp[0] * dp[i-1]
* @param n
* @return
*/
public int numTrees(int n) {
if (n <= 1) {
return 1;
}
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++) {
for (int j = 1; j <= i; j++) {
dp[i] += (dp[i - j] * dp[j - 1]);
}
}
return dp[n];
}
}
}

View File

@ -0,0 +1,70 @@
package cn.whaifree.leetCode.Greedy;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/2/25 22:21
* @注释
*/
public class LeetCode122 {
@Test
public void test() {
System.out.println(new Solution1().maxProfit(new int[]{7, 1, 5, 3, 6, 4}));
System.out.println(new Solution1().maxProfit(new int[]{1}));
}
class Solution {
/**
* 随时可以买卖那么只要有跌的我都不要
* 上帝视角只要涨我就全要
*
* 7跌 1涨5 4涨6 跌4
*
* @param prices
* @return
*/
public int maxProfit(int[] prices) {
int maxProfit = 0;
for (int i = 0; i < prices.length; i++) {
if (i > 0 && prices[i] - prices[i - 1] > 0) {
maxProfit += prices[i] - prices[i - 1];
}
}
return maxProfit;
}
}
class Solution1 {
/**
* dp[i] 表示当天可获得的收益
* dp[i] = dp[i-1] + if(prices[i-1] < price[i]){prices[i] - price[i-1]}
*
* @param prices
* @return
*/
public int maxProfit(int[] prices) {
int[] dp = new int[prices.length];
for (int i = 1; i < prices.length; i++) {
dp[i] = dp[i - 1];
if (prices[i - 1] < prices[i]) {
// 挣钱
dp[i] += prices[i] - prices[i - 1];
}
}
return dp[prices.length - 1];
}
}
}

View File

@ -1,44 +0,0 @@
package cn.whaifree.leetCode.Greedy;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/2/25 22:21
* @注释
*/
public class LeetCode322 {
@Test
public void test() {
System.out.println(new Solution().maxProfit(new int[]{7, 1, 5, 3, 6, 4}));
}
class Solution {
/**
* 随时可以买卖那么只要有跌的我都不要
* 上帝视角只要涨我就全要
*
* 7跌 1涨5 4涨6 跌4
*
* @param prices
* @return
*/
public int maxProfit(int[] prices) {
int maxProfit = 0;
for (int i = 0; i < prices.length; i++) {
if (i > 0 && prices[i] - prices[i - 1] > 0) {
maxProfit += prices[i] - prices[i - 1];
}
}
return maxProfit;
}
// TODO 动态规划
}
}

View File

@ -16,7 +16,9 @@ import java.util.concurrent.locks.ReentrantLock;
public class LeetCode53 { public class LeetCode53 {
@Test @Test
public void test() { public void test() {
System.out.println(new LeetCode53().new Solution().maxSubArray(new int[]{-2, 1, -3, 4, -1, 2, 1, -5, 4})); System.out.println(new Solution1().maxSubArray(new int[]{-2, 1, -3, 4, -1, 2, 1, -5, 4}));
System.out.println(new Solution1().maxSubArray(new int[]{5,4,-1,7,8}));
} }
class Solution { class Solution {
@ -44,5 +46,39 @@ public class LeetCode53 {
} }
class Solution1 {
/**
* 动态规化
* dp[i] 表示i出最大子序列的和
* if dp[i-1]+nums[i]>0 dp[i] = dp[i-1] + nums[i]
* else dp[i] = nums[i]
*
* [-2,1,-3,4,-1,2,1,-5,4]
* [-2,1,-3,4,3,5,6,1,5]
*
* @param nums
* @return
*/
public int maxSubArray(int[] nums) {
int[] dp = new int[nums.length];
dp[0] = nums[0];
int max = dp[0];
for (int i = 1; i < nums.length; i++) {
dp[i] = Math.max(nums[i], dp[i - 1] + nums[i]);
max = Math.max(dp[i], max);
// if (dp[i - 1] > 0 && dp[i - 1] + nums[i] > 0) {
// dp[i] = dp[i - 1] + nums[i];
// } else {
// dp[i] = nums[i];
// }
// max = Math.max(dp[i], max);
}
return max;
}
}
} }

View File

@ -108,6 +108,9 @@ public class Tes1 {
} }
private static final Object lock = new Object();
private static int count = 0;
public static void main(String[] args) { public static void main(String[] args) {
// 创建一个TreeNode对象并创建其对应的PhantomReference和ReferenceQueue // 创建一个TreeNode对象并创建其对应的PhantomReference和ReferenceQueue
TreeNode treeNode = new TreeNode(11); TreeNode treeNode = new TreeNode(11);
@ -130,6 +133,37 @@ public class Tes1 {
} else { } else {
System.out.println("TreeNode对象还未被垃圾回收器回收"); System.out.println("TreeNode对象还未被垃圾回收器回收");
} }
Thread t1 = new Thread(() -> {
synchronized (lock) {
while (count < 10) {
System.out.println("Thread 1: " + count++);
lock.notify();
}
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
Thread t2 = new Thread(() -> {
synchronized (lock) {
while (count < 20) {
System.out.println("Thread 2: " + count++);
lock.notify();
}
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
t1.start();
t2.start();
} }
} }

View File

@ -0,0 +1,59 @@
package cn.whaifree.redo.redo_24_3_9;
import org.junit.Test;
import java.util.Arrays;
import java.util.HashSet;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/10 12:32
* @注释
*/
public class LeetCode134 {
@Test
public void test() {
int[] gas = {5,1,2,3,4};
int[] cost = {4,4,1,5,1};
int result = new Solution().canCompleteCircuit(gas, cost);
System.out.println(result);
}
class Solution {
/**
*
* @param gas
* @param cost
* @return
*/
public int canCompleteCircuit(int[] gas, int[] cost) {
//判断是否一定能绕圈
int sumGas = 0;
for (int i : gas) {
sumGas += i;
}
int sumCost = 0;
for (int i : cost) {
sumCost += i;
}
if (sumGas<sumCost) return -1;
int iHave = 0;
int length = gas.length;
int indexGas = 0;
for (int i = 0; i < length; i++) {
iHave += gas[i];
if (iHave < cost[i]) {
iHave = 0;
indexGas = (i+1) % length;
}else {
iHave -= cost[i];
}
}
return indexGas;
}
}
}

View File

@ -0,0 +1,46 @@
package cn.whaifree.redo.redo_24_3_9;
import cn.whaifree.leetCode.model.TreeNode;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/10 19:03
* @注释
*/
public class LeetCode236 {
@Test
public void test() {
TreeNode root = TreeNode.constructTreeByArray(3, 5, 1, 6, 2, 0, 8, null, null, 7, 4);
System.out.println(new Solution().lowestCommonAncestor(root, root.left, root.left.right).val);
}
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return null;
}
// 如果是p或者q 返回该节点
if (root.val == p.val || root.val == q.val) {
return root;
}
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
// 如果左右都不为空则找到了公共父节点
if (left != null && right != null) {
return root;
}
// 左边为空则左边不存在要找的p或者q返回右边
if (left != null) {
return left;
}else {
return right;
}
}
}
}

View File

@ -0,0 +1,34 @@
package cn.whaifree.redo.redo_24_3_9;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/10 19:38
* @注释
*/
public class LeetCode376 {
class Solution {
public int wiggleMaxLength(int[] nums) {
if (nums.length == 1) {
return 1;
}
// 使用curSub作为当前差值
// 使用preSub作为上一个和curSub相反地差值, 在不断增加的过程中presub依然记录的是减去的过程
int curSub = 0;
int preSub = 0;
int res = 0;
for (int i = 1; i < nums.length; i++) {
curSub = nums[i] - nums[i - 1];
if ((curSub < 0 && preSub >= 0) || (curSub > 0 && preSub <= 0)) {
preSub = curSub;
res++;
}
}
return res;
}
}
}

View File

@ -0,0 +1,78 @@
package cn.whaifree.redo.redo_24_3_9;
import org.junit.Test;
import java.util.Arrays;
import java.util.Comparator;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/9 12:25
* @注释
*/
public class LeetCode435 {
@Test
public void test() {
// [[1,2],[2,3],[3,4],[1,3]]
// int[][] intervals = new int[][]{{1, 2}, {2, 3}, {3, 4}, {1, 3}};
int[][] intervals = new int[][]{{1, 4}, {3, 6}, {7, 10},{5, 8}, {9, 12}};
// [ [1,2], [1,2], [1,2] ]
// int[][] intervals = new int[][]{{1, 2}, {1, 2}, {1, 2}};
System.out.println(new Solution1().eraseOverlapIntervals(intervals));
}
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
// 按照起始位置从小到大排序
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0] - o2[0];
}
});
// 如果i的起始位置比i-1的终点位置要小那么就需要移除并更新结束位置为minlast,last
// 如果起始位置比i-1大那么直接进入下个区间并count++
int normalCount = 1;
for (int i = 1; i < intervals.length; i++) {
if (intervals[i][0] < intervals[i - 1][1]) {
// 需要去掉
intervals[i][1] = Math.min(intervals[i][1], intervals[i - 1][1]);
}else {
normalCount++;
}
}
return intervals.length - normalCount;
}
}
class Solution1 {
public int eraseOverlapIntervals(int[][] intervals) {
// 按照起始位置从小到大排序
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[1] - o2[1];
}
});
int right = intervals[0][1];
int count = 1;
for (int i = 1; i < intervals.length; i++) {
if (intervals[i][0] < right) {
// 需要去掉
// right = right;
}else {
right = intervals[i][1];
count++;
}
}
return intervals.length - count;
}
}
}

View File

@ -0,0 +1,45 @@
package cn.whaifree.redo.redo_24_3_9;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/10 12:12
* @注释
*/
public class LeetCode45 {
@Test
public void test() {
int[] nums = {2, 3, 1, 1, 4};
int jump = new Solution().jump(nums);
System.out.println(jump);
}
class Solution {
public int jump(int[] nums) {
if (nums.length == 1) {
return 0;
}
// 在最大覆盖范围内向前
int maxCover = 0;
int curCover = 0;
int jumpCount = 0;
for (int i = 0; i < nums.length; i++) {
maxCover = Math.max(maxCover, i + nums[i]);
if (i == curCover) {
jumpCount++;
curCover = maxCover;
// 必须等待区间增加后再判断是否到末位
if (maxCover >= nums.length - 1) {
break;
}
}
}
return jumpCount;
}
}
}

View File

@ -0,0 +1,54 @@
package cn.whaifree.redo.redo_24_3_9;
import cn.whaifree.leetCode.model.TreeNode;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/10 19:17
* @注释
*/
public class LeetCode450 {
@Test
public void test() {
new Solution().deleteNode(TreeNode.constructTreeByArray(), 5).printTree();
}
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) {
return null;
}
return circle(root, key);
}
public TreeNode circle(TreeNode root,int key) {
if (root == null) {
return null;
}
if (root.val == key) {
// 将root.left全部移动到root.right.left.left....
TreeNode index = root.right;
// 如果右边没有节点直接返回左边的
if (index == null) {
return root.left;
}
while (index.left != null) {
index = index.left;
}
index.left = root.left;
return root.right;
}
if (root.val < key) {
root.right = circle(root.right, key);
}else {
root.left = circle(root.left, key);
}
return root;
}
}
}

View File

@ -0,0 +1,54 @@
package cn.whaifree.redo.redo_24_3_9;
import org.junit.Test;
import java.util.Arrays;
import java.util.Comparator;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/9 13:22
* @注释
*/
public class LeetCode452 {
@Test
public void test()
{
int[][] points = {{10,16},{2,8},{1,6},{7,12}};
int[][] points1 = {{1, 2}, {3, 4}, {5, 6},{7,8}};
int[][] points2 = {{1,2},{2,3},{3,4},{4,5}};
System.out.println(new Solution().findMinArrowShots(points2));
}
class Solution {
/**
* [[-2147483646,-2147483645],[2147483646,2147483647]]
* @param points
* @return
*/
public int findMinArrowShots(int[][] points) {
Arrays.sort(points, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
if (o1[1]<o2[1])return -1;
return 1;
}
});
int arrow = 1;
for (int i = 1; i < points.length; i++) {
if (points[i][0] <= points[i - 1][1]) {
// 在这个区间内
points[i][1] = points[i - 1][1];
}else {
arrow++;
}
}
return arrow;
}
}
}

View File

@ -0,0 +1,40 @@
package cn.whaifree.redo.redo_24_3_9;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/10 12:07
* @注释
*/
public class LeetCode509 {
@Test
public void test() {
int result = new Solution().fib(4);
System.out.println(result);
}
class Solution {
/**
* 含义
* 递推 F(n) = F(n - 1) + F(n - 2)
* 初始化 F(0) = 0 F(1) = 1
* 推演
* @param n
* @return
*/
public int fib(int n) {
if (n <= 1) {
return n;
}
int[] dp = new int[n + 1];
dp[1] = 1;
for (int i = 2; i < dp.length; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
}
}

View File

@ -0,0 +1,44 @@
package cn.whaifree.redo.redo_24_3_9;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/9 13:52
* @注释
*/
public class LeetCode738 {
@Test
public void test() {
System.out.println(new Solution().monotoneIncreasingDigits(668841));
}
class Solution {
public int monotoneIncreasingDigits(int n) {
// 从右往左 找到 最后一个 递减的前后两个数
// 前一个数-1后面全部用9替换
char[] c = String.valueOf(n).toCharArray();
int target = Integer.MAX_VALUE;
for (int i = c.length - 1; i > 0; i--) {
if (c[i] < c[i - 1]) {
// 注意一定要在这对c[i]--,668841 等第二个8变成了7就又不是递增了所以不能简单地找到前后两个递减就结束
c[i - 1]--;
target = i;
}
}
for (int i = target; i < c.length; i++) {
c[i] = '9';
}
return Integer.valueOf(new String(c));
}
}
}

View File

@ -0,0 +1,49 @@
package cn.whaifree.redo.redo_24_3_9;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/9 13:38
* @注释
*/
public class LeetCode763 {
@Test
public void test() {
new Solution().partitionLabels("ababcbacadefegdehijhklij").forEach(
i -> System.out.println(i)
);
}
class Solution {
public List<Integer> partitionLabels(String s) {
List<Integer> res = new ArrayList<>();
int[] map = new int[26];
// 计算最晚出现的索引
// 如果当前i==最晚出现的索引需要划分一次
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
map[chars[i] - 'a'] = i;
}
int left = -1;
int far = 0;
for (int i = 0; i < chars.length; i++) {
// 遍历的过程中找到前面区间的最远边界
far = Math.max(far, map[chars[i] - 'a']);
if (i == far) {
res.add(i - left);
left = i;
}
}
return res;
}
}
}

View File

@ -0,0 +1,68 @@
package cn.whaifree.redo.redo_24_3_9;
import cn.whaifree.leetCode.model.TreeNode;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/10 11:35
* @注释
*/
public class LeetCode968 {
@Test
public void test() {
System.out.println(new Solution().minCameraCover(TreeNode.constructTreeByArray(1,2,null,3,4,5,null,null,6)));
}
class Solution {
int total = 0;
/**
* 监控二叉树
* 2 被覆盖
* 0 没覆盖
* 1 有摄像头
*
* 0 0 | 0 1 | 1 1 | 0 2 | 1 2 | 2 2
*
*
* 根节点必然只能被监控根节点的父节点放摄像头
* @param root
* @return
*/
public int minCameraCover(TreeNode root) {
// 判断根节点的左右
int rootIndex = Tracking(root);
if (rootIndex == 0) {
total++;
}
return total;
}
public int Tracking(TreeNode root) {
if (root == null) {
return 2; // 空节点表示被覆盖
}
int left = Tracking(root.left);
int right = Tracking(root.right);
if (left == 2 && right == 2) {
return 0;
}
// 如果左右存在没被覆盖的这个点就放置一个摄像头
if (left == 0 || right == 0) {
total++;
return 1;
}
// 如果左右子节点有摄像头本节点为被覆盖的
if (left ==1 || right == 1) {
return 2;
}
return -1;
}
}
}

View File

@ -0,0 +1,138 @@
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/10 12:49
* @注释
*/
public class TestInteger {
public static void main(String[] args) {
Integer a = new Integer(100);
Integer b = new Integer(100);
System.out.println(a == b); //false 两个对象指向
/**
* 0 new #2 <java/lang/Integer>
* 3 dup
* 4 bipush 100
* 6 invokespecial #3 <java/lang/Integer.<init> : (I)V>
* 9 astore_1
* 10 new #2 <java/lang/Integer>
* 13 dup
* 14 bipush 100
* 16 invokespecial #3 <java/lang/Integer.<init> : (I)V>
* 19 astore_2
* 20 getstatic #4 <java/lang/System.out : Ljava/io/PrintStream;>
* 23 aload_1
* 24 aload_2
* 25 if_acmpne 32 (+7)
* 28 iconst_1
* 29 goto 33 (+4)
* 32 iconst_0
* 33 invokevirtual #5 <java/io/PrintStream.println : (Z)V>
*/
Integer c = new Integer(100);
int d = 100;
System.out.println(c == d); //true
/**
* 36 new #2 <java/lang/Integer>
* 39 dup
* 40 bipush 100
* 42 invokespecial #3 <java/lang/Integer.<init> : (I)V>
* 45 astore_3
* 46 bipush 100
* 48 istore 4
* 50 getstatic #4 <java/lang/System.out : Ljava/io/PrintStream;>
* 53 aload_3
* 54 invokevirtual #6 <java/lang/Integer.intValue : ()I> // Integer自动拆箱为int
* 57 iload 4
* 59 if_icmpne 66 (+7)
* 62 iconst_1
* 63 goto 67 (+4)
* 66 iconst_0
* 67 invokevirtual #5 <java/io/PrintStream.println : (Z)V>
*/
Integer e = new Integer(100);
Integer f = 100;
System.out.println(e == f); //false
/**
* 70 new #2 <java/lang/Integer>
* 73 dup
* 74 bipush 100
* 76 invokespecial #3 <java/lang/Integer.<init> : (I)V>
* 79 astore 5
* 81 bipush 100
* 83 invokestatic #7 <java/lang/Integer.valueOf : (I)Ljava/lang/Integer;> //自动装箱之后其实是一个new Integer(100)
* 86 astore 6
* 88 getstatic #4 <java/lang/System.out : Ljava/io/PrintStream;>
* 91 aload 5
* 93 aload 6
* 95 if_acmpne 102 (+7)
* 98 iconst_1
* 99 goto 103 (+4)
* 102 iconst_0
* 103 invokevirtual #5 <java/io/PrintStream.println : (Z)V>
*/
Integer g = 100; // Integer i = Integer.valueOf(100) -128-127 会缓存如果超过这个范围就是new Integer
Integer h = 100; // Integer i = Integer.valueOf(100)
System.out.println(g == h); //true
/**
* 106 bipush 100
* 108 invokestatic #7 <java/lang/Integer.valueOf : (I)Ljava/lang/Integer;>
* 111 astore 7
* 113 bipush 100
* 115 invokestatic #7 <java/lang/Integer.valueOf : (I)Ljava/lang/Integer;>
* 118 astore 8
* 120 getstatic #4 <java/lang/System.out : Ljava/io/PrintStream;>
* 123 aload 7
* 125 aload 8
* 127 if_acmpne 134 (+7)
* 130 iconst_1
* 131 goto 135 (+4)
* 134 iconst_0
* 135 invokevirtual #5 <java/io/PrintStream.println : (Z)V>
*/
// java API中对Integer类型的valueOf的定义如下对于-128到127之间的数会进行缓存
// sipush指令用于加载-32768到32767之间的整数常量到操作数栈中而bipush指令则用于加载-128到127之间的整数常量到操作数栈中
Integer j = 128;
Integer i = 128;
System.out.println(i == j); //false
/**
* 138 sipush 128
* 141 invokestatic #7 <java/lang/Integer.valueOf : (I)Ljava/lang/Integer;>
* 144 astore 9
* 146 sipush 128
* 149 invokestatic #7 <java/lang/Integer.valueOf : (I)Ljava/lang/Integer;>
* 152 astore 10
* 154 getstatic #4 <java/lang/System.out : Ljava/io/PrintStream;>
* 157 aload 10
* 159 aload 9
* 161 if_acmpne 168 (+7)
* 164 iconst_1
* 165 goto 169 (+4)
* 168 iconst_0
* 169 invokevirtual #5 <java/io/PrintStream.println : (Z)V>
* 172 return
*/
}
}
class gg {
private static final int _1MB = 1024 * 1024;
public static void testAllocation() {
byte [] allocation1, allocation2, allocation3, allocation4;
allocation1 = new byte[2 *_1MB];
allocation2 = new byte[2 *_1MB];
allocation3 = new byte[2 *_1MB];
allocation4 = new byte[4 *_1MB];
}
public static void main(String[] args) {
testAllocation();
}
}