Kimi LeetCode 3563. 移除相邻字符后字典序最小的字符串 Java实现
根据搜索结果以下是 LeetCode 3563. Lexicographically Smallest String After Adjacent Removals 的 Java 实现。题目理解- 连续 定义字母表中绝对差为 1 或 25 的两个字母即 a↔b, b↔c, ..., y↔z, z↔a- 每次操作可删除任意一对相邻且连续的字母- 删除后字符串会压缩两边的字符会重新相邻- 目标经过任意次操作后得到字典序最小的字符串核心思路使用 区间 DP1. dp[i][j] 表示子串 s[i..j) 经过若干次删除操作后能得到的最小字典序字符串2. 初始化 dp[i][i] 空串3. 对于每个区间 s[i..j)- 保留 s[i]结果为 s[i] dp[i1][j]- 删除 s[i]需要找到 s[k]i k j使得 s[i] 和 s[k] 连续且中间部分 s[i1..k) 能被完全删空即 dp[i1][k] 结果为 dp[k1][j]- 取两者中字典序更小的时间复杂度O(n³)空间复杂度O(n²)Java 实现javaclass Solution {public String lexicographicallySmallestString(String s) {final int n s.length();// dp[i][j]: 子串 s[i..j) 经过若干次删除后能得到的最小字典序字符串String[][] dp new String[n 1][n 1];// 初始化空区间结果为 for (int i 0; i n; i) {dp[i][i] ;}// 按区间长度从小到大计算for (int d 1; d n; d) {for (int i 0; i d n; i) {final int j i d;// 情况1保留 s[i]结果为 s[i] dp[i1][j]String minString s.charAt(i) dp[i 1][j];// 情况2尝试删除 s[i]// 需要找到 s[k] 与 s[i] 连续且 s[i1..k) 能被完全删空for (int k i 1; k j; k) {if (isConsecutive(s.charAt(i), s.charAt(k)) dp[i 1][k].isEmpty()) {String candidate dp[k 1][j];if (candidate.compareTo(minString) 0) {minString candidate;}}}dp[i][j] minString;}}return dp[0][n];}// 判断两个字母是否连续在循环字母表中差1或25private boolean isConsecutive(char a, char b) {int diff Math.abs(a - b);return diff 1 || diff 25;}}代码说明要点 说明dp[i][j] 左闭右开区间 s[i..j) 的最小字典序结果dp[i][i] 空子串结果为空字符串保留 s[i] s.charAt(i) dp[i1][j]删除 s[i] 需找到 s[k] 与 s[i] 连续且 dp[i1][k] 为空中间全删完然后取 dp[k1][j]isConsecutive diff 1 处理 a-b, b-c 等diff 25 处理 z-a 的循环情况复杂度分析- 时间复杂度O(n³)外层两重循环遍历所有 O(n²) 个区间内层循环最多 O(n) 次查找 k- 空间复杂度O(n²)存储 dp 数组如需优化可以考虑使用记忆化搜索 缓存的方式或者进一步优化状态转移。