博客
关于我
LeetCode——每日一题(回溯问题)
阅读量:324 次
发布时间:2019-03-04

本文共 13406 字,大约阅读时间需要 44 分钟。

package 计算机程序算法分类.dfs深度优先广度优先问题;import org.junit.Test;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;/** * @Classname 电话号码全排列问题复现 * @Description TODO * @Date 2021/4/11 14:57 * @Created by xjl */public class 电话号码全排列问题复现 {    public List
letterCombinations(String digits) { ArrayList
result = new ArrayList<>(); if (digits.length() == 0) return result; //开始访问的位置 int index = 0; //存储电话号码的映射 Map
map = new HashMap<>(); map.put('2', "abc"); map.put('3', "def"); map.put('4', "ghi"); map.put('5', "jkl"); map.put('6', "mno"); map.put('7', "pqrs"); map.put('8', "tuv"); map.put('9', "wxyz"); //进行的递归的方法 dfs2(result, map, digits, index, new StringBuilder()); return result; } private void dfs(ArrayList
result, Map
map, String digits, int index, StringBuilder stringBuilder) { if (index == digits.length()) { result.add(stringBuilder.toString()); return; } else { char digit = digits.charAt(index); //获取当前的字符串 String number = map.get(digit); for (int i = 0; i < number.length(); i++) { //添加 stringBuilder.append(number.charAt(i)); //递归调用 dfs(result, map, digits, index + 1, stringBuilder); //回溯 stringBuilder.deleteCharAt(stringBuilder.length() - 1); } } } private void dfs2(ArrayList
result, Map
map, String digits, int index, StringBuilder sb) { if (index == digits.length()) { result.add(sb.toString()); return; } else { char ch = digits.charAt(index); String str = map.get(ch); for (int i = 0; i < str.length(); i++) { sb.append(str.charAt(i)); dfs2(result, map, digits, index + 1, sb); sb.deleteCharAt(sb.length() - 1); } } } @Test public void test() { List
strings = letterCombinations("23"); for (String s : strings) { System.out.print(s + " "); } }}

package 计算机程序算法分类.dfs深度优先广度优先问题;import org.junit.Test;import java.util.ArrayList;import java.util.List;/** * @Classname 全排列问题没有重复 * @Description TODO * @Date 2021/4/11 15:14 * @Created by xjl */public class 全排列问题没有重复 {    @Test    public void test() {        List
> permute = permute(new int[]{1, 2, 3}); for (List
ss : permute) { for (int s : ss) { System.out.print(s + " "); } System.out.println(); } } //没有重复的 public List
> permute(int[] nums) { List
> result = new ArrayList<>(); if (nums.length == 0) { return result; } int index = 0; boolean[] vis = new boolean[nums.length]; List
list = new ArrayList<>(); dfs(result, list, index, nums, vis); return result; } private void dfs(List
> result, List
list, int index, int[] nums, boolean[] vis) { if (index == nums.length) { result.add(new ArrayList<>(list)); } else { for (int i = 0; i < nums.length; i++) { if (vis[i]==false){ vis[i]=true; list.add(nums[i]); dfs(result, list, index + 1, nums,vis); list.remove(list.size() - 1); vis[i]=false; } } } }}

字母的全排列问题

package 计算机程序算法分类.dfs深度优先广度优先问题;import leetcode练习题.permute;import org.junit.Test;import java.util.ArrayList;import java.util.List;/** * @Classname 全排列的字母的问题 * @Description TODO * @Date 2021/4/11 15:28 * @Created by xjl */public class 全排列的字母的问题 {    //要求有顺序的输出    public List
permute(String strings) { List
result = new ArrayList<>(); if (strings.length() == 0) return result; int index = 0; String str = ""; boolean[] vis = new boolean[strings.length()]; dfs(result, index, str, vis, strings); return result; } private void dfs(List
result, int index, String str, boolean[] vis, String arr) { if (index == arr.length()) { result.add(str); return; } else { for (int i = 0; i < arr.length(); i++) { if (vis[i] == false) { str += arr.charAt(i); //表示已经访问过了 vis[i] = true; dfs(result, index + 1, str, vis, arr); //删除的最后一个 str = str.substring(0, str.length() - 1); vis[i] = false; } } } } @Test public void test() { List
permute = permute("abc"); for (String s : permute) { System.out.println(s); }// String str = "123456";// System.out.println(str.substring(0, str.length() - 1)); }}
package 计算机程序算法分类.dfs深度优先广度优先问题;import leetcode练习题.permute;import org.junit.Test;import java.util.ArrayList;import java.util.Comparator;import java.util.List;import java.util.PriorityQueue;/** * @Classname 全排列的字母的问题 * @Description TODO * @Date 2021/4/11 15:28 * @Created by xjl */public class 全排列的字母的问题 {    //要求有顺序的输出    public List
permute(String strings) { List
result = new ArrayList<>(); if (strings.length() == 0) return result; int index = 0; String str = ""; boolean[] vis = new boolean[strings.length()]; //利用的最小的堆来保证的顺序的 PriorityQueue
pq = new PriorityQueue<>(new Comparator
() { @Override public int compare(String o1, String o2) { return o1.compareTo(o2); } }); dfs(pq, index, str, vis, strings); while (!pq.isEmpty()) { result.add(pq.poll()); } return result; } private void dfs(PriorityQueue
pq, int index, String str, boolean[] vis, String arr) { if (index == arr.length()) { pq.add(str); return; } else { for (int i = 0; i < arr.length(); i++) { if (vis[i] == false) { str += arr.charAt(i); //表示已经访问过了 vis[i] = true; dfs(pq, index + 1, str, vis, arr); //删除的最后一个 str = str.substring(0, str.length() - 1); vis[i] = false; } } } } @Test public void test() { List
permute = permute("bac"); for (String s : permute) { System.out.println(s); }// String str = "123456";// System.out.println(str.substring(0, str.length() - 1)); }}

package 计算机程序算法分类.dfs深度优先广度优先问题;import java.util.ArrayList;import java.util.List;/** * @Classname 括号的生成 * @Description TODO * @Date 2021/4/11 15:50 * @Created by xjl */public class 括号的生成 {    public List
generateParenthesis(int n) { List
result = new ArrayList
(); StringBuilder sb = new StringBuilder(); dfs(result, sb, 0, 0, n); return result; } public void dfs(List
ans, StringBuilder cur, int left, int right, int max) { //判断是的字符串的长度的以便于终止函数的跳出 if (cur.length() == max * 2) { //添加到结果集中 ans.add(cur.toString()); return; } //左边的小于最大值得时候就加入左括号 if (left < max) { cur.append('('); dfs(ans, cur, left + 1, right, max); //这里使用了回溯的方法 删除最后的一个 cur.deleteCharAt(cur.length() - 1); } //当右边的小于左边的时候加入右边括号 if (right < left) { cur.append(')'); dfs(ans, cur, left, right + 1, max); cur.deleteCharAt(cur.length() - 1); } }}

package 计算机程序算法分类.dfs深度优先广度优先问题;import java.util.ArrayList;import java.util.List;/** * @Classname 复原IP地址93 * @Description TODO * @Date 2021/4/11 15:57 * @Created by xjl */public class 复原IP地址93 {    static final int SEG_COUNT = 4;    int[] segments = new int[SEG_COUNT];    public List
restoreIpAddresses(String s) { List
ans = new ArrayList
(); dfs(ans, s, 0, 0); return ans; } public void dfs(List
ans, String s, int seg_number, int index) { // 如果找到了 4 段 IP 地址并且遍历完了字符串,那么就是一种答案 if (seg_number == SEG_COUNT) { //遍历完成了全部的字符串 if (index == s.length()) { StringBuffer ipAddr = new StringBuffer(); for (int i = 0; i < SEG_COUNT; ++i) { ipAddr.append(segments[i]); if (i != SEG_COUNT - 1) { ipAddr.append('.'); } } //添加到返回的结果中 ans.add(ipAddr.toString()); } return; } // 如果还没有找到 4 段 IP 地址就已经遍历完了字符串,那么提前回溯 if (index == s.length()) { return; } // 由于不能有前导零,如果当前数字为 0,那么这一段 IP 地址只能为 0 if (s.charAt(index) == '0') { segments[seg_number] = 0; dfs(ans, s, seg_number + 1, index + 1); } // 一般情况,枚举每一种可能性并递归 int addr = 0; for (int segEnd = index; segEnd < s.length(); segEnd++) { addr = addr * 10 + (s.charAt(segEnd) - '0'); if (addr > 0 && addr <= 255) { segments[seg_number] = addr; dfs(ans, s, seg_number + 1, segEnd + 1); } else { break; } } }}

 

package 计算机程序算法分类.dfs深度优先广度优先问题;import java.util.LinkedList;import java.util.Queue;/** * @Classname 路径和112 * @Description TODO * @Date 2021/4/11 18:21 * @Created by xjl */public class 路径和112 {    public class TreeNode {        int val;        TreeNode left;        TreeNode right;        TreeNode() {        }        TreeNode(int val) {            this.val = val;        }        TreeNode(int val, TreeNode left, TreeNode right) {            this.val = val;            this.left = left;            this.right = right;        }    }    /**     * @description TODO 这个是的采用的是dfs也就是的递归的思想来实现     * @param: root     * @param: targetSum     * @date: 2021/4/12 16:38     * @return: boolean     * @author: xjl     */    public boolean hasPathSum(TreeNode root, int targetSum) {        if (root == null) return false;        if (root.left == null && root.right == null) {            if (targetSum == root.val) {                return true;            }        }        boolean l = hasPathSum(root.left, targetSum - root.val);        boolean r = hasPathSum(root.right, targetSum - root.val);        //只有左边或者右边都是有一个就行        return l || r;    }    /**     * @description TODO  采用的是广度遍历的方式来实现 每一次查看给节点是叶子节点且同时这个目标的值等于弹出的值如果是的话那就到了叶子节点     * @param: root     * @param: targetSum     * @date: 2021/4/12 16:32     * @return: boolean     * @author: xjl     */    public boolean hasPathSum2(TreeNode root, int targetSum) {        if (root == null) {            return false;        }        //用于存放的二叉树的节点        Queue
queNode = new LinkedList
(); //存放数值 Queue
queVal = new LinkedList
(); queNode.offer(root); queVal.offer(root.val); while (!queNode.isEmpty()) { //弹出节点的值 TreeNode now = queNode.poll(); //弹出这个值得结果 int temp = queVal.poll(); if (now.left == null && now.right == null) { if (temp == targetSum) { return true; } continue; } //遍历左边 if (now.left != null) { //添加这个左节点 queNode.offer(now.left); //向值里面添加 queVal.offer(now.left.val + temp); } //遍历右边 if (now.right != null) { //添加右边的节点 queNode.offer(now.right); //向值里面添加 queVal.offer(now.right.val + temp); } } return false; }}

package 计算机程序算法分类.dfs深度优先广度优先问题;import java.util.ArrayList;import java.util.List;/** * @Classname 路径和113 * @Description TODO * @Date 2021/4/11 18:22 * @Created by xjl */public class 路径和113 {    public class TreeNode {        int val;        TreeNode left;        TreeNode right;        TreeNode() {        }        TreeNode(int val) {            this.val = val;        }        TreeNode(int val, TreeNode left, TreeNode right) {            this.val = val;            this.left = left;            this.right = right;        }    }    public List
> pathSum(TreeNode root, int targetSum) { List
> result = new ArrayList<>(); dfs(root, targetSum, new ArrayList<>(), result); return result; } public void dfs(TreeNode root, int sum, List
list,List
> result) { //如果节点为空直接返回 if (root == null) return; //把当前节点值加入到list中 list.add(new Integer(root.val)); //如果到达叶子节点,就不能往下走了,直接return if (root.left == null && root.right == null) { //如果到达叶子节点,并且sum等于叶子节点的值,说明我们找到了一组, //要把它放到result中 if (sum == root.val) result.add(new ArrayList(list)); //注意别忘了把最后加入的结点值给移除掉,因为下一步直接return了, //不会再走最后一行的remove了,所以这里在rerurn之前提前把最后 //一个结点的值给remove掉。 list.remove(list.size() - 1); //到叶子节点之后直接返回,因为在往下就走不动了 return; } //如果没到达叶子节点,就继续从他的左右两个子节点往下找,注意到 //下一步的时候,sum值要减去当前节点的值 dfs(root.left, sum - root.val, list, result); dfs(root.right, sum - root.val, list, result); //我们要理解递归的本质,当递归往下传递的时候他最后还是会往回走, //我们把这个值使用完之后还要把它给移除,这就是回溯 list.remove(list.size() - 1); }}

 

转载地址:http://hwjh.baihongyu.com/

你可能感兴趣的文章
mysql 两列互转
查看>>
MySQL 中开启二进制日志(Binlog)
查看>>
MySQL 中文问题
查看>>
MySQL 中日志的面试题总结
查看>>
mysql 中的all,5分钟了解MySQL5.7中union all用法的黑科技
查看>>
MySQL 中的外键检查设置:SET FOREIGN_KEY_CHECKS = 1
查看>>
Mysql 中的日期时间字符串查询
查看>>
mysql 中索引的问题
查看>>
MySQL 中锁的面试题总结
查看>>
MySQL 中随机抽样:order by rand limit 的替代方案
查看>>
MySQL 为什么需要两阶段提交?
查看>>
mysql 为某个字段的值加前缀、去掉前缀
查看>>
mysql 主从
查看>>
mysql 主从 lock_mysql 主从同步权限mysql 行锁的实现
查看>>
mysql 主从互备份_mysql互为主从实战设置详解及自动化备份(Centos7.2)
查看>>
mysql 主从关系切换
查看>>
MYSQL 主从同步文档的大坑
查看>>
mysql 主键重复则覆盖_数据库主键不能重复
查看>>
Mysql 事务知识点与优化建议
查看>>
Mysql 优化 or
查看>>