LeetCode 回溯算法专题
回溯法是一个纯暴力的搜索算法,它可以解决组合、切割、子集、排列和棋盘问题。回溯可以被抽象成为一个n叉树,树的宽度就是for循环的次数,树的高度可以抽象为递归的深度。
回溯模板:
1 private void backtracking("原始参数") { 2 if ("终止条件") { 3 //收集结果 4 return; 5 } 6 7 //遍历集合元素 8 for (int i = "循环开始的参数"; i < "循环结束的参数"; i++) { 9 10 //做出选择 11 12 //递归 13 backtracking("新的参数"); 14 15 //撤销选择 16 } 17 }
剑指 Offer 38. 字符串的排列 - 力扣(LeetCode)
1 class Solution { 2 private Set<String> res = new HashSet<>(); 3 4 public String[] permutation(String s) { 5 backtracking(s.toCharArray(), "", new boolean[s.length()]); 6 return res.toArray(new String[res.size()]); 7 } 8 9 private void backtracking(char[] chars, String tmp, boolean[] visited) { 10 if (tmp.length() == chars.length) { 11 res.add(tmp); 12 return; 13 } 14 for (int i = 0; i < chars.length; i++) { 15 if (visited[i]) { 16 continue; 17 } 18 visited[i] = true; 19 backtracking(chars, tmp + chars[i], visited); 20 visited[i] = false; 21 } 22 } 23 }
1 class Solution { 2 private List<List<Integer>> res = new ArrayList<>(); 3 4 public List<List<Integer>> permute(int[] nums) { 5 backtracking(nums, new ArrayList<Integer>(), new boolean[nums.length]); 6 return res; 7 } 8 9 private void backtracking(int[] nums, List<Integer> tmp, boolean[] visited) { 10 if (tmp.size() == nums.length) { 11 res.add(new ArrayList(tmp)); 12 return; 13 } 14 for (int i = 0; i < nums.length; i++) { 15 if (visited[i]) { 16 continue; 17 } 18 visited[i] = true; 19 tmp.add(nums[i]); 20 backtracking(nums, tmp, visited); 21 visited[i] = false; 22 tmp.remove(tmp.size() - 1); 23 } 24 } 25 }
1 class Solution { 2 List<String> res = new ArrayList<>(); // 所有可能的有效 IP 地址 3 List<String> path = new ArrayList<>(); // 在回溯中临时存储一个 IP 地址 4 5 public List<String> restoreIpAddresses(String s) { 6 // 非法 IP 地址 7 if (s.length() < 3 || s.length() > 13) { 8 return res; 9 } 10 backtracking(s, 0, 0); 11 return res; 12 } 13 14 /** 15 * 判断字符串是否为合法的 IP 地址段 16 * @param s: 只包含数字的字符串 17 * @return 如果字符串是为合法的 IP 地址段则返回 true,否则返回 false 18 */ 19 private boolean isValidIP(String s) { 20 if (s.charAt(0) == '0' && s.length() > 1) { 21 return false; 22 } 23 if (s.length() > 3) { 24 return false; 25 } 26 if (Integer.parseInt(s) > 255) { 27 return false; 28 } 29 return true; 30 } 31 32 /** 33 * 回溯复原 IP 地址 34 * @param s: 只包含数字的字符串 35 * @param splitIndex: 分割点 36 * @param level: 回溯的第几段 IP 地址 37 */ 38 private void backtracking(String s, int splitIndex, int level) { 39 if (level > 3) { 40 res.add(String.join(".", path)); 41 return; 42 } 43 for (int i = splitIndex; i < s.length(); i++) { 44 if ((s.length() - i - 1) > 3 * (3 - level)) { 45 continue; 46 } 47 if (!isValidIP(s.substring(splitIndex, i + 1))) { 48 continue; 49 } 50 path.add(s.substring(splitIndex, i + 1)); 51 backtracking(s, i + 1, level + 1); 52 path.remove(path.size() - 1); 53 } 54 } 55 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南