2.3 dfs 回溯

力扣 39组合总和

public class combinationSum_1 {
    static List<List<Integer>> res;
    static LinkedList<Integer> tmp ;
    public static List<List<Integer>> combinationSum(int[] candidates, int target) {
        res = new ArrayList<>();
        tmp = new LinkedList<>();
        dfs(candidates, target,0,0);
        return res;
    }


    private static void dfs(int[] candidates, int target, int cur_sum, int idx) {
        //1.end
        if(cur_sum == target) {
            res.add(new ArrayList<>(tmp));
            return;
        }
       else if (cur_sum > target){
            return;
        }
        //2.choose
        for(int i = idx; i < candidates.length; i++){
            cur_sum += candidates[i];
            tmp.add(candidates[i]);
            dfs(candidates, target, cur_sum, i);
            //3.撤销
            cur_sum -= candidates[i];
            tmp.removeLast();
        }
    }

力扣 46 全排列

public class allArrangement {
    public static List<List<Integer>> permute(int[] nums){
        List<List<Integer>> res = new LinkedList<>();
        LinkedList<Integer> track = new LinkedList<>();
        backtrack(nums, track, res);
        return res;
    }


    // 路径:记录在 track 中
    // 选择列表:nums 中不存在于 track 的那些元素
    // 结束条件:nums 中的元素全都在 track 中出现
    private static void backtrack(int[] nums, LinkedList<Integer> track, List<List<Integer>> res) {
        //1.结束条件
        if (track.size() == nums.length){
            res.add(new LinkedList<>(track));
            return;
        }
        //在选择列表里面选择
        for (int i=0; i<nums.length; i++){
            if(track.contains(nums[i])) continue;
            //选择他
            track.add(nums[i]);
            //进一步深度优先遍历
            backtrack(nums, track, res);
            //撤销上一步的选择
            track.remove(track.size()-1);
        }
    }


    public static void main(String[] args){
        int[] nums ={1,2,3};
        List<List<Integer>> res = permute(nums);
        System.out.println(res);
    }
}

力扣 401. 二进制手表

public class ReadBinaryWatch_1 {
    // 小时最多有3个,分钟最多有5个
    public static List<String> readBinaryWatch(int num) {
        List<String> ans = new ArrayList<>();
        if(num >= 9) return ans;
        //first 3
        for(int i = 0; i <= 3; i++) {
            if(num - i > 5) continue;
            List<String> h = new ArrayList<>();
            dfs(i, 0, 0, new int[4], h);//小时 new int[4] --> {0,0,1,1} 表示0011即3
            List<String> m = new ArrayList<>();
            dfs(num - i, 0, 0, new int[6], m);//分钟


            for(String hh : h) {
                for(String mm : m) {
                    if(mm.length() == 1) {
                        mm = "0" + mm;
                    }
                    ans.add(hh + ":" + mm);
                }
            }
        }
        return ans;
    }


    public static void dfs(int num, int idx, int cnt, int[] arr, List<String> res) {
        //1.结束dfs条件
        if(cnt == num) {
            StringBuilder sb = new StringBuilder();
            //{0,0,1,1} --> '0011'
            for(int val : arr) {
                sb.append(val);
            }
            int tmp = Integer.parseInt(sb.toString(), 2);//将二进制字符换成int,如parseInt("1100110", 2) returns 102
            if((tmp > 11 && arr.length == 4) || (tmp > 59 && arr.length == 6)) return;
            res.add(Integer.toString(tmp));
            return;
        }
        //2.选择列表中不停选择值并遍历
        for(int i = idx; i < arr.length; i++) {
            //2.1选择他
            arr[i] = 1;
            //2.2进一步dfs
            dfs(num, i + 1, cnt + 1, arr, res);
            //2.3撤销选择
            arr[i] = 0;
        }
    }


    public static void main(String[] args) {
        List<String> res = readBinaryWatch(1);
        System.out.println(res);
    }
}
posted @ 2021-08-08 14:45  weidalin  阅读(37)  评论(0)    收藏  举报