diff --git a/ForJdk17/src/main/java/cn/whaifree/interview/Dws/P1.java b/ForJdk17/src/main/java/cn/whaifree/interview/Dws/P1.java
index b019d45..f90ecd2 100644
--- a/ForJdk17/src/main/java/cn/whaifree/interview/Dws/P1.java
+++ b/ForJdk17/src/main/java/cn/whaifree/interview/Dws/P1.java
@@ -1,6 +1,7 @@
package cn.whaifree.interview.Dws;
import cn.whaifree.leetCode.model.TreeNode;
+import org.junit.Test;
import java.util.*;
@@ -15,21 +16,22 @@ public class P1 {
class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
- *
+ *
* 每日温度
+ *
* @param dailyTemperatures int整型一维数组
* @return int整型一维数组
*/
- public int[] temperatures (int[] dailyTemperatures) {
+ public int[] temperatures(int[] dailyTemperatures) {
// write code here
// 每一天需要等待几天会出现更高温
// 单调栈
int[] res = new int[dailyTemperatures.length];
Deque stack = new LinkedList<>();
for (int i = 0; i < dailyTemperatures.length; i++) {
- while (!stack.isEmpty()&&dailyTemperatures[i] > dailyTemperatures[stack.peek()]) {
+ while (!stack.isEmpty() && dailyTemperatures[i] > dailyTemperatures[stack.peek()]) {
Integer pop = stack.pop();
- res[pop] = i -pop;
+ res[pop] = i - pop;
}
stack.push(i);
}
@@ -42,49 +44,71 @@ public class P1 {
class Solution {
- static class Node{
- int parentIndex;
- int currentIndex;
- int flag;
- TreeNode currentNode;
- public Node(int parentIndex, int currentIndex, int flag, TreeNode currentNode) {
+ public static void main(String[] args) {
+ Solution solution = new Solution();
+ // {1,2,3,#,#,4,5},1
+ TreeNode treeNode = TreeNode.constructTree(new Integer[]{1, 2, 3, null, null, 4, 5});
+ System.out.println(solution.cyclicShiftTree(treeNode, 1));
+ }
+
+ // Node类封装了节点的层次信息,便于后续重构指针
+ static class Node {
+ int parentIndex;// 父节点在当前层的位置
+ int currentIndex; // 当前节点在该层的索引位置
+ boolean leftFlag; // 标记当前节点是左孩子(0)还是右孩子(1)
+ TreeNode currentNode; // 当前节点的引用
+
+ public Node(int parentIndex, int currentIndex, boolean leftFlag, TreeNode currentNode) {
this.parentIndex = parentIndex;
this.currentIndex = currentIndex;
- this.flag = flag;
+ this.leftFlag = leftFlag;
this.currentNode = currentNode;
}
}
+
/**
* https://blog.csdn.net/ouyang_peng/article/details/143254632
*
- *
* @param root TreeNode类
- * @param k int整型
+ * @param k int整型
* @return TreeNode类
*/
- public TreeNode cyclicShiftTree (TreeNode root, int k) {
- // write code here
+ public TreeNode cyclicShiftTree(TreeNode root, int k) {
+ if (root == null) return null; //
+ // 存储每层的节点信息,最后用来重构
List> levels = new ArrayList<>();
Queue queue = new LinkedList<>();
- queue.offer(new Node(0,0,0,root));
- int parentNum = 1;
- int nextNum = 0;
- List tempLevel = new ArrayList<>();
+ // 根节点加入队列
+ queue.offer(new Node(0, 0, true, root));
- while (!queue.isEmpty()){
+ // `parentNum`记录当前层节点数,`nextNum`记录下一层节点数
+ int parentNum = 1; // 根节点只有1个节点
+ int nextNum = 0; // 层次遍历,每次进入一个到这一层,就++,就能统计这一层的元素个数
+ List tempLevel = new ArrayList<>(); // 当前层的节点列表
+
+ while (!queue.isEmpty()) {
Node node = queue.poll();
- tempLevel.add(node);
+ tempLevel.add(node); // 加入当前层
parentNum--;
- if (node.currentNode.left!=null){
- queue.offer(new Node(node.currentIndex,nextNum++,0,node.currentNode.left));
+
+ if (node.currentNode.left != null) {
+ queue.offer(
+ new Node(
+ node.currentIndex, // 父节点位置, node为父亲节点在当前层的位置
+ nextNum++, // 当前节点位置
+ true,
+ node.currentNode.left
+ )
+ );
}
- if (node.currentNode.right!=null){
- queue.offer(new Node(node.currentIndex,nextNum++,1,node.currentNode.right));
+ if (node.currentNode.right != null) {
+ queue.offer(new Node(node.currentIndex, nextNum++, false, node.currentNode.right));
}
- if (parentNum==0){
+ if (parentNum == 0) {
+ // 每层最后一个元素
parentNum = nextNum;
nextNum = 0;
levels.add(tempLevel);
@@ -92,25 +116,52 @@ class Solution {
}
}
- int depth = levels.size()-1;
+ int depth = levels.size() - 1;
+ // 从最底层开始,逐层向上进行位移操作。
+ // 对于每一层,首先计算出这一层需要位移的步数,然后根据位移步数调整每个节点的左右子节点指针。
for (int i = depth; i > 0; i--) {
- List parentLev = levels.get(i - 1);
+ List parentLev = levels.get(i - 1); // 上一层的节点
int parentSize = parentLev.size();
+ // 这一层节点左右都设置为空
for (Node node : parentLev) {
- node.currentNode.left=null;
- node.currentNode.right=null;
+ node.currentNode.left = null;
+ node.currentNode.right = null;
}
- int move = k%(2*parentSize);
- tempLevel = levels.get(i);
+ // 计算这一层需要位移的位置,位移后在哪个父节点之下
+ // 上一层的个数决定位移个数
+ /**
+ * 比如
+ * 1
+ \
+ 3
+ / \
+ 4 5
+ 第3层的位移个数是根据第二层有几个元素确定的,这个位置和父亲节点的距离为move
+ */
+ int move = k % (2 * parentSize);
+ tempLevel = levels.get(i); // 本层
for (Node node : tempLevel) {
- int targetIndex = node.flag == 0 ? (node.parentIndex + move / 2) % parentSize : (node.parentIndex + (move + 1) / 2) % parentSize;
- int targetFlag = node.flag == 0?move%2:(move+1);
+ int targetIndex = 0; // 在本层的新位置
+ if (node.leftFlag) {
+ targetIndex = (node.parentIndex + move / 2) % parentSize;
+ } else {
+ targetIndex = (node.parentIndex + (move + 1) / 2) % parentSize;
+ }
+
+
+ int targetFlag = 0;
+ if (node.leftFlag) {
+ targetFlag = move % 2;
+ } else {
+ targetFlag = (move + 1) % 2;
+ }
+
Node targetP = parentLev.get(targetIndex);
- if (targetFlag==0){
+ if (targetFlag == 0) {
targetP.currentNode.left = node.currentNode;
- }else {
+ } else {
targetP.currentNode.right = node.currentNode;
}
}
diff --git a/ForJdk17/src/main/java/cn/whaifree/leetCode/LeetCode221.java b/ForJdk17/src/main/java/cn/whaifree/leetCode/LeetCode221.java
new file mode 100644
index 0000000..1b5c126
--- /dev/null
+++ b/ForJdk17/src/main/java/cn/whaifree/leetCode/LeetCode221.java
@@ -0,0 +1,57 @@
+package cn.whaifree.leetCode;
+
+import org.junit.Test;
+
+/**
+ * @version 1.0
+ * @Author whai文海
+ * @Date 2024/11/20 12:20
+ * @注释
+ */
+public class LeetCode221 {
+
+ @Test
+ public void test() {
+ Solution solution = new Solution();
+ System.out.println(solution.maximalSquare(new char[][]{{'1', '0', '1', '0', '0'}, {'1', '0', '1', '1', '1'}, {'1', '1', '1', '1', '1'}, {'1', '0', '0', '1', '0'}}));
+ }
+
+ class Solution {
+ /**
+ * 如果三个位置都为x,那么本节点就是变长为x的
+ *
+ * @param matrix
+ * @return
+ */
+ public int maximalSquare(char[][] matrix) {
+ int maxLen = 0;
+ int[][] dp = new int[matrix.length][matrix[0].length];
+ for (int i = 0; i < matrix[0].length; i++) {
+ if (matrix[0][i] == '1') {
+ dp[0][i] = 1;
+ maxLen = 1;
+ }
+ }
+
+ for (int i = 0; i < matrix.length; i++) {
+ if (matrix[i][0] == '1') {
+ dp[i][0] = 1;
+ maxLen = 1;
+ }
+ }
+ for (int i = 1; i < matrix.length; i++) {
+ for (int j = 1; j < matrix[0].length; j++) {
+ if (matrix[i - 1][j] == '1' && matrix[i][j - 1] == '1' && matrix[i - 1][j - 1] == '1') {
+ if (matrix[i][j] == '1') {
+ dp[i][j] = Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
+ }
+ } else if (matrix[i][j] == '1') {
+ dp[i][j] = 1;
+ }
+ maxLen = Math.max(maxLen, dp[i][j]);
+ }
+ }
+ return maxLen * maxLen;
+ }
+ }
+}
diff --git a/ForJdk17/src/main/java/cn/whaifree/leetCode/LeetCode673.java b/ForJdk17/src/main/java/cn/whaifree/leetCode/LeetCode673.java
new file mode 100644
index 0000000..61e8c25
--- /dev/null
+++ b/ForJdk17/src/main/java/cn/whaifree/leetCode/LeetCode673.java
@@ -0,0 +1,85 @@
+package cn.whaifree.leetCode;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.function.IntPredicate;
+
+/**
+ * @version 1.0
+ * @Author whai文海
+ * @Date 2024/11/20 12:57
+ * @注释
+ */
+public class LeetCode673 {
+
+ @Test
+ public void test() {
+ // 2 2 2 2 2
+ System.out.println(new Solution().findNumberOfLIS(new int[]{1}));
+ }
+
+ class Solution {
+ /**
+ * dp[i] 表示0-i最长递增子序列,子序列长度
+ * count[i] 以nums[i]为结尾的字符串,最长递增子序列的个数为count[i]
+ *
+ * @param nums
+ * @return
+ */
+ public int findNumberOfLIS(int[] nums) {
+ if (nums.length <= 1) return nums.length;
+ int max = 0;
+
+ int[] dp = new int[nums.length];
+ // 初始化
+ Arrays.fill(dp, 1);
+ int[] count = new int[nums.length];
+ Arrays.fill(count, 1);
+ for (int i = 1; i < nums.length; i++) {
+ int left = i - 1;
+ while (left >= 0) {
+ if (nums[left] < nums[i]) {
+
+ if (dp[left] + 1 > dp[i]) {
+ // 找到一个更长的子序列
+ // 那么数量应该为left的count,表示最长递增子序列的个数更新为left处的
+ count[i] = count[left];
+ } else if (dp[left] + 1 == dp[i]) {
+ // 如果找到的子序列长度和原来的一样,那么就加上left处的
+ // 增加left处的最长递增,因为这时最长递增子序列的长度都一样
+ count[i] += count[left];
+ }
+
+ dp[i] = Math.max(dp[i], dp[left] + 1); // 最长递增子序列的长度
+ }
+ max = Math.max(max, dp[i]);
+ left--;
+ }
+
+ }
+
+ int res = 0;
+ // 统计所有最长递增子序列的个数为max的
+ for (int i = 0; i < nums.length; i++) {
+ if (dp[i] == max) {
+ res += count[i];
+ }
+ }
+ return res;
+ }
+
+ }
+}
+class Test989 {
+ private int a = 10;
+ int b = 20;
+ static int c = 30;
+
+ public static void main(String[] args) {
+ Test989 t = new Test989(); // 创建 Test 类的对象
+ System.out.println(t.a); // 错误:a 是 private 的
+ System.out.println(t.b); // 正确:b 是实例变量
+// System.out.println(this.c); // 正确:c 是 static 变量
+ }
+}
diff --git a/ForJdk17/src/main/java/cn/whaifree/leetCode/LeetCode931.java b/ForJdk17/src/main/java/cn/whaifree/leetCode/LeetCode931.java
new file mode 100644
index 0000000..770ca31
--- /dev/null
+++ b/ForJdk17/src/main/java/cn/whaifree/leetCode/LeetCode931.java
@@ -0,0 +1,58 @@
+package cn.whaifree.leetCode;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * @version 1.0
+ * @Author whai文海
+ * @Date 2024/11/20 11:59
+ * @注释
+ */
+public class LeetCode931 {
+
+ @Test
+ public void test() {
+ Solution solution = new Solution();
+ // [[2,1,3],[6,5,4],[7,8,9]]
+ System.out.println(solution.minFallingPathSum(new int[][]{{2, 1}, {6, 5}}));
+ }
+
+ class Solution {
+ /**
+ * int[i][j] 表示从最顶到i j 的价值
+ *
+ * 第一层为对应格子的值
+ *
+ * 最最左边和最右边只能由 2个推出
+ *
+ * @param matrix
+ * @return
+ */
+ public int minFallingPathSum(int[][] matrix) {
+ int n = matrix.length;
+ int[][] dp = new int[n][n];
+ // 第一层
+ for (int i = 0; i < matrix.length; i++) {
+ dp[0][i] = matrix[0][i];
+ }
+
+ for (int i = 1; i < n; i++) {
+ // 每层 , 第一个元素只能由上一个
+ dp[i][0] = Math.min(dp[i - 1][0], dp[i - 1][1])+ matrix[i][0];
+ for (int j = 1; j < n - 1; j++) {
+ dp[i][j] = Math.min(Math.min(dp[i - 1][j - 1], dp[i - 1][j]), dp[i - 1][j + 1]) + matrix[i][j];
+ }
+ dp[i][n - 1] = Math.min(dp[i - 1][n - 1], dp[i - 1][n - 2]) + matrix[i][n - 1];
+ }
+
+ int min = Integer.MAX_VALUE;
+ for (int i = 0; i < n; i++) {
+ min = Math.min(min, dp[n - 1][i]);
+ }
+ return min;
+ }
+ }
+
+}
diff --git a/SpringDemo/pom.xml b/SpringDemo/pom.xml
index 4418e5c..07cc19a 100644
--- a/SpringDemo/pom.xml
+++ b/SpringDemo/pom.xml
@@ -30,6 +30,20 @@
17
+
+
+
+ org.apache.poi
+ poi
+ 5.0.0
+
+
+
+ org.apache.poi
+ poi-ooxml
+ 5.0.0
+
+
com.github.ben-manes.caffeine
diff --git a/SpringDemo/src/main/java/cn/whaifree/springdemo/config/TransactionConfig.java b/SpringDemo/src/main/java/cn/whaifree/springdemo/config/TransactionConfig.java
index 3bdbee3..7be3782 100644
--- a/SpringDemo/src/main/java/cn/whaifree/springdemo/config/TransactionConfig.java
+++ b/SpringDemo/src/main/java/cn/whaifree/springdemo/config/TransactionConfig.java
@@ -1,97 +1,97 @@
-package cn.whaifree.springdemo.config;
-
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.jdbc.datasource.DataSourceTransactionManager;
-import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.TransactionDefinition;
-import org.springframework.transaction.TransactionManager;
-import org.springframework.transaction.TransactionStatus;
-import org.springframework.transaction.annotation.TransactionManagementConfigurer;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.transaction.support.DefaultTransactionDefinition;
-import org.springframework.transaction.support.TransactionCallback;
-import org.springframework.transaction.support.TransactionTemplate;
-
-import javax.sql.DataSource;
-
-/**
- * @version 1.0
- * @Author whai文海
- * @Date 2024/11/15 16:37
- * @注释
- */
-@Configuration
-@Slf4j
-public class TransactionConfig implements TransactionManagementConfigurer {
-
-
- @Autowired
- private TransactionTemplate transactionTemplate;
-
- //配置事务管理器
- @Bean
- public TransactionManager transactionManager(DataSource dataSource) {
- DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
- // 打印参数
- log.info("transactionManager: {}", transactionManager);
- log.info("dataSource: {}", dataSource);
- return transactionManager;
- }
-
- @Resource(name="txManager1")
- private PlatformTransactionManager txManager1;
-
- // 创建事务管理器1
- @Bean(name = "txManager1")
- public PlatformTransactionManager txManager(DataSource dataSource) {
- return new DataSourceTransactionManager(dataSource);
- }
-
- @Override
- public TransactionManager annotationDrivenTransactionManager() {
- return txManager1;
- }
-
- @Transactional(value="txManager1")
- public void addUser() {
-
- }
-
- public void addUser2() {
- DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
- transactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
- transactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
- TransactionStatus transaction = txManager1.getTransaction(transactionDefinition);
- try {
- txManager1.commit(transaction);
- } catch (Exception e) {
- txManager1.rollback(transaction);
- }
- }
-
- /**
- * 编程事务
- * TransactionTemplate
- * PlatformTransactionManager
- * DataSourceTransactionManager
- */
-
- public void adduser3() {
- Object execute = transactionTemplate.execute(new TransactionCallback