class Solution { private static final int MOD = 1000000007;
public int concatenatedBinary(int n) { long result = 0; int shift = 0; // 移位数 for (int i = 1; i <= n; i++) { // 判断一个数是否为2的幂 if ((i & (i - 1)) == 0) { shift++; } result = ((result << shift) | i) % MOD; } return (int) result; } }
在将项目升级到 Spring Boot 3.2.x + Java 17 后,项目在启动阶段直接退出,没有 Exception in thread "main" 或 Caused by,导致问题难以定位。
最初怀疑过:
Knife4j / Swagger
Hutool 工具类
枚举定义
配置文件错误
但检查后发现都不是原因。
报错信息
开启 DEBUG 日志后,启动过程中出现如下关键信息:
1 2 3 4 5
Creating MapperFactoryBean with name 'userMapper' ... Exception encountered during context initialization - cancelling refresh attempt: java.lang.IllegalArgumentException: Invalid value type for attribute 'factoryBeanObjectType': java.lang.String
子矩阵修改 对(x1,y1)到(x2,y2)加上val diff[x1][y1] += val diff[x2+1][y1] -= val diff[x1][y2+1] -= val diff[x2+1][y2+1] += val
模板
1 2 3 4 5 6 7 8 9 10 11 12
public class Main { // 求数组的差分数组 public int[] Diff(int[] nums) { int n = nums.length; int[] diff = new int[n]; diff[0] = nums[0]; for (int i = 0; i < n; i++) { diff[i] = diff[i + 1] - nums[i]; } return diff; } }
class Solution { // 求和 >= target 的最短子数组长度 public int minSubArrayLen(int target, int[] nums) { int n = nums.length; int left = 0, sum = 0; int ans = Integer.MAX_VALUE;
for (int right = 0; right < n; right++) { sum += nums[right]; while (sum >= target) { ans = Math.min(ans, right - left + 1); sum -= nums[left]; left++; } } return ans == Integer.MAX_VALUE ? 0 : ans; } }
适用范围
连续子数组 / 子串
满足某种约束(和、字符种类数等)
最短 / 最长 区间问题
例题
904.水果成篮 你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。
class Solution { // 返回每个元素右侧第一个更大的元素 public int[] nextGreater(int[] nums) { int n = nums.length; int[] res = new int[n]; Arrays.fill(res, -1); Deque<Integer> stack = new ArrayDeque<>();
for (int i = 0; i < n; i++) { while (!stack.isEmpty() && nums[stack.peek()] < nums[i]) { int idx = stack.pop(); res[idx] = nums[i]; } stack.push(i); } return res; } }
while (!queue.isEmpty()) { int cur = queue.poll(); for (int next : graph[cur]) { if (!visited[next]) { visited[next] = true; queue.offer(next); } } } }
class HanoiTower{ public void move(int n, char from, char to, char aux){ if (n == 1){ System.out.println("Move disk 1 from " + from + " to " + to); return; } move(n-1, from, aux, to); System.out.println("Move disk " + n + " from " + from + " to " + to); move(n-1, aux, to, from); } }
class Solution { public int ans; public int diameterOfBinaryTree(TreeNode root) { dfs(root); return ans; } private int dfs(TreeNode node){ if(node == null){ return -1; } int l = dfs(node.left) + 1; int r = dfs(node.right) + 1; ans = Math.max(l + r, ans); return Math.max(l,r); } }
class Iteration { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> ans = new ArrayList<>(); Stack<TreeNode> stack = new Stack<>(); TreeNode curr = root;
class Mirris { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> ans = new ArrayList<>(); TreeNode curr = root; while (curr != null) { if (curr.left == null) { ans.add(curr.val); curr = curr.right; } else { // 找到左子树的最右节点(前驱) TreeNode pre = curr.left; while (pre.right != null && pre.right != curr) { pre = pre.right; } if (pre.right == null) { // 建立线索 pre.right = curr; curr = curr.left; } else { // 线索已存在,说明左子树已遍历完 pre.right = null; // 恢复树结构 ans.add(curr.val); curr = curr.right; } } } return ans; } }
时间复杂度:O(n)
空间复杂度:O(1)
4.测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
public class Main { public static void main(String[] args) { TreeNode root = new TreeNode(1); root.right = new TreeNode(2); root.right.left = new TreeNode(3);