Leetcode总结之Backtracking

本文我们就Leetcode中的一个类型的题目backtracking进行一系列的总结和归纳。
backtracking这个方法本质是建立在递归的基础上,不断尝试新的路径,这里关键是每次尝试完以后需要退回来也就是回溯。

如果你已经找到了解决方案,那么返回成功

for(现在位置可以的所有可能选择){

选择其中一个方案然后沿着路径前进一步

使用递归的方法从新的位置解决问题

如果新的位置可以成功解决,向上一级返回成功

从现在位置恢复到循环之前的位置 }

如果到这里表示仍然没有成功,返回失败

下面我们来看一下的例题:

package DFS;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.Stack;

public class DFSProblem {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
    }

    /*
     * 140. Word Break II     * s = "catsanddog",dict = ["cat", "cats", "and", "sand", "dog"].A solution is ["cats and dog", "cat sand dog"].
     * 这里聪明的点就在于,不是一个一个的加的,是一个词一个词的加的,遇到一个词,再继续往下走.     *所有的可能选项就是包含在dict里面的所有的单词,而不是一个一个的字母。     *
     */
    public ArrayList<String> wordBreak(String s, Set<String> dict) {
        ArrayList<String> res = new ArrayList<String>();
        if (s == null || s.length() == 0)
            return res;
        helper(s, dict, 0, "", res);
        return res;
    }
    private void helper(String s, Set<String> dict, int start, String item,ArrayList<String> res) {
        if (start >= s.length()) {
            res.add(item);
            return;
        }
        StringBuilder str = new StringBuilder();
        for (int i = start; i < s.length(); i++) {
            str.append(s.charAt(i));
            if (dict.contains(str.toString())) {
                String newItem = item.length() > 0 ? (item + " " + str.toString()) : str.toString();
                helper(s, dict, i + 1, newItem, res);
            }
        }}

    /*
     * Number of Islands 12.19 by Mingyang
     * 直接设一个叫count的值,没遇到一个1,就把所有相连的1全部变为0,这样,到底遇到几次1,就是最终有几个小岛啦
     */
    public int numIslands(char[][] grid) {
        if (grid == null || grid.length == 0 || grid[0].length == 0)
            return 0;
        int count = 0;

        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                if (grid[i][j] == ‘1‘) {
                    count++;
                    dfs(grid, i, j);
                }
            }
        }
        return count;
    }

    public void dfs(char[][] grid, int i, int j) {
        // validity checking
        if (i < 0 || j < 0 || i > grid.length - 1 || j > grid[0].length - 1)
            return;

        // if current cell is water or visited
        if (grid[i][j] != ‘1‘)
            return;

        // set visited cell to ‘0‘
        grid[i][j] = ‘0‘;

        // merge all adjacent land
        dfs(grid, i - 1, j);
        dfs(grid, i + 1, j);
        dfs(grid, i, j - 1);
        dfs(grid, i, j + 1);
    }

    /*
     * Palindrome Partitioning 12.17 by Mingyang Return all possible palindrome
     * partitioning of s.
     */
    public List<List<String>> partition(String s) {
        List<String> item = new ArrayList<String>();
        List<List<String>> res = new ArrayList<List<String>>();
        if (s == null || s.length() == 0)
            return res;
        dfs(s, 0, item, res);
        return res;
    }

    public void dfs(String s, int start, List<String> item,
            List<List<String>> res) {
        if (start == s.length()) {
            res.add(new ArrayList<String>(item));
            return;
        }

        for (int i = start; i < s.length(); i++) {
            String str = s.substring(start, i + 1);// 每一轮dfs进来都是先取第一个数,start
                                                    // index
            if (isPalindrome(str)) {
                item.add(str);
                dfs(s, i + 1, item, res);// 上面取到i,所以下一个start index就是i+1
                item.remove(item.size() - 1);
            }
        }
    }

    // 也可以再少用一个变量
    public void dfs(String s, List<String> temp, List<List<String>> res) {
        if (s.length() == 0) {
            res.add(new ArrayList<String>(temp));
            return;
        }
        int len = s.length();
        for (int i = 1; i < len; i++) {
            String subs = s.substring(0, i);
            if (isPalindrome(subs)) {
                temp.add(subs);
                String resub = s.substring(i);
                dfs(resub, temp, res);
                temp.remove(temp.size() - 1);
            }
        }
    }

    public boolean isPalindrome(String s) {
        int low = 0;
        int high = s.length() - 1;
        while (low < high) {
            if (s.charAt(low) != s.charAt(high))
                return false;
            low++;
            high--;
        }
        return true;
    }

    /*
     * 93. Restore IP Addresses 12.16 by Mingyang
     * 这里不用StringBuffer因为我们最后要检查每一小块string到底是否符合要求
     */
    public static List<String> restoreIpAddresses1(String s) {
        List<String> res = new ArrayList<String>();
        dfs(res, s, 0, "", 4);
        return res;
    }

    public static void dfs(List<String> res, String s, int start, String item,
            int count) {
        if (start == s.length() && count == 0) {
            System.out.println("Succ" + item);
            res.add(item);
            return;
        }
        if (count <= 0) {
            System.out.println("meet 0" + item + count);
            return;
        }
        StringBuffer sb = new StringBuffer();
        for (int i = start; i < s.length(); i++) {
            sb.append(s.charAt(i));
            if (isValid(sb.toString())) {
                dfs(res, s, i + 1, item.isEmpty() ? (sb.toString())
                        : (item + ‘.‘ + sb.toString()), --count);
                count++;
                System.out.println("return" + item + ":" + count);
            } else {
                return;// 为什么需要写这个呢,因为这个可以防止多余的计算,比如数字太大2552551113,会让下面的isValid失效,就是省去多余的
            }
        }
    }

    public static List<String> restoreIpAddresses(String s) {
        List<String> res = new ArrayList<String>();
        String item = new String();
        if (s.length() < 4 || s.length() > 12)
            return res;

        dfs(s, 0, item, res);
        return res;
    }

    public static void dfs(String s, int start, String item, List<String> res) {
        if (start == 3 && isValid(s)) {
            res.add(item + s);
            return;
        }
        for (int i = 0; i < 3 && i < s.length() - 1; i++) { // 注意不要出界啊,否则不好玩了
            String substr = s.substring(0, i + 1);
            if (isValid(substr))
                dfs(s.substring(i + 1, s.length()), start + 1, item + substr
                        + ‘.‘, res);
        }
    }

    public static boolean isValid(String s) {
        if (s.charAt(0) == ‘0‘)
            return s.equals("0"); // 如果以0开头的,必须要检查是否等于001,011等不合格的,若开头为0,整个数必须为0
        System.out.println(s);
        int num = Integer.parseInt(s);

        if (num <= 255 && num > 0)
            return true;
        else
            return false;
    }

    /*
     * 212. Word Search II 12.17 by Mingyang 这么做可以在word
     * search的基础之上做,但是效率不高,所以后面可以用tire tree
     */
    public List<String> findWords(char[][] board, String[] words) {
        ArrayList<String> result = new ArrayList<String>();
        int m = board.length;
        int n = board[0].length;
        for (String word : words) {
            boolean flag = false;
            boolean[][] visited = new boolean[m][n];
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    char[][] newBoard = new char[m][n];
                    for (int x = 0; x < m; x++)
                        for (int y = 0; y < n; y++)
                            newBoard[x][y] = board[x][y];
                    if (dfs4(newBoard, word, i, j, 0, visited)) {
                        flag = true;
                    }
                }
            }
            if (flag) {
                result.add(word);
            }
        }
        return result;
    }

    /*
     * 79. Word Search 12.16 by Mingyang 这里的起点就是遍历所有的点,找出这个起点
     * 我自己做的时候,用了一个StringBuffer来进行加减,判断条件就是sb和word相等,但是!每次加减sb造成了时间上的浪费
     * 这里我们用一个index来就好了,每次完了以后,index+1.这样的话我们就可以通过index和word的长度来判断
     * 另外有一个技巧就是index不用自己加加,只用加1,这样不会改变index的本质,不用退回来再减一个了。
     */
    public boolean exist(char[][] board, String word) {
        int m = board.length;
        int n = board[0].length;
        boolean[][] visited = new boolean[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (dfs4(board, word, 0, i, j, visited))
                    return true;
            }
        }
        return false;
    }

    public boolean dfs4(char[][] board, String word, int index, int rowindex,
            int colindex, boolean[][] visited) {
        if (index == word.length())
            return true;
        if (rowindex < 0 || colindex < 0 || rowindex >= board.length
                || colindex >= board[0].length)
            return false;
        if (visited[rowindex][colindex])
            return false;
        if (board[rowindex][colindex] != word.charAt(index))
            return false;
        visited[rowindex][colindex] = true;
        boolean res = dfs4(board, word, index + 1, rowindex - 1, colindex,
                visited)
                || dfs4(board, word, index + 1, rowindex + 1, colindex, visited)
                || dfs4(board, word, index + 1, rowindex, colindex + 1, visited)
                || dfs4(board, word, index + 1, rowindex, colindex - 1, visited);
        visited[rowindex][colindex] = false;
        return res;
    }

    /*
     * 90. Subsets II 12.16 by Mingyang
     * 这里我们将后面重复的部分算进来,就是当有重复出现的时候,结果不能重复,我就加了一个boolean array
     */
    public static List<List<Integer>> subsetsWithDup(int[] nums) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        ArrayList<Integer> item = new ArrayList<Integer>();
        if (nums.length == 0 || nums == null)
            return res;
        Arrays.sort(nums);
        boolean[] array = new boolean[nums.length];
        for (int len = 1; len <= nums.length; len++)
            dfs3(nums, 0, len, item, res, array);
        res.add(new ArrayList<Integer>());
        return res;
    }

    public static void dfs3(int[] S, int start, int len, List<Integer> item,
            List<List<Integer>> res, boolean[] array) {
        if (item.size() == len) {
            res.add(new ArrayList<Integer>(item));
            return;
        }
        for (int i = start; i < S.length; i++) {
            if (i != 0 && S[i] == S[i - 1] && array[i - 1] == false)
                continue;
            item.add(S[i]);
            array[i] = true;
            dfs3(S, i + 1, len, item, res, array);
            item.remove(item.size() - 1);
            array[i] = false;
        }
    }

    /*
     * 78. Subsets 12.16 by Mingyang
     * 注意这里虽然感觉很像combine,但是这个array可以随意的,可以为任意数的array,所以还是得用array来
     * ,并且那个array要sort一下,记住,千万不要忘了加空集
     */
    public static List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        ArrayList<Integer> item = new ArrayList<Integer>();
        if (nums.length == 0 || nums == null)
            return res;
        Arrays.sort(nums);
        for (int len = 1; len <= nums.length; len++)
            dfs3(nums, 0, len, item, res);
        res.add(new ArrayList<Integer>());
        return res;
    }

    public static void dfs3(int[] S, int start, int len, List<Integer> item,
            List<List<Integer>> res) {
        if (item.size() == len) {
            res.add(new ArrayList<Integer>(item));
            return;
        }
        for (int i = start; i < S.length; i++) {
            item.add(S[i]);
            dfs3(S, i + 1, len, item, res);
            item.remove(item.size() - 1);
        }
    }

    /*
     * 77. Combinations 12.16 by Mingyang
     * 这里有个一个start的多的参数以后就可以保证所有序列按顺序输出的,并且不会重复 12-13-14-23-24-34
     */
    public static List<List<Integer>> combine(int n, int k) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        if (n <= 0 || n < k)
            return res;
        List<Integer> item = new ArrayList<Integer>();
        dfs2(n, k, 1, item, res);// because it need to begin from 1-------从1开始的哦
        return res;
    }

    private static void dfs2(int n, int k, int start, List<Integer> item,
            List<List<Integer>> res) {
        if (item.size() == k) {
            res.add(new ArrayList<Integer>(item));// because item is
                                                    // ArrayList<T> so it will
                                                    // not disappear from stack
                                                    // to stack
            return;
        }
        for (int i = start; i <= n; i++) { // 这里多加了一个start,这样就不用再判断重复了
            item.add(i);
            dfs2(n, k, i + 1, item, res);
            item.remove(item.size() - 1);
        }
    }

    /*
     * Permutations II 12.13 by Mingyang 唯一的区别就是在这个题目中元素集合可以出现重复。
     * 这给我们带来一个问题就是如果不对重复元素加以区别, 那么类似于{1,1,2}这样的例子我们会有重复结果出现。那么如何避免这种重复呢?
     * 方法就是对于重复的元素循环时跳过递归函数的调用,只对第一个未被使用的进行递归,
     * 我们那么这一次结果会出现在第一个的递归函数结果中,而后面重复的会被略过。 如果第一个重复元素前面的元素还没在当前结果中,那么我们不需要进行递归。
     * 首先我们要对元素集合排序,从而让重复元素相邻,接下来就是一行代码对于重复元素和前面元素使用情况的判断即可。
     * 这样的解法是带有一般性的,把这个代码放到Permutations中也是正确的,所以如果熟悉的话,
     * 面试时如果碰到这个题目建议直接实现这个代码,不要假设元素没有重复,当然可以跟面试官讨论,不过一般来说都是要考虑这个情况的哈。
     */
    public List<List<Integer>> permuteUnique(int[] nums) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        if (nums == null || nums.length == 0)
            return res;
        Arrays.sort(nums);
        boolean[] visited = new boolean[nums.length];
        List<Integer> temp = new ArrayList<Integer>();
        dfs4(nums, visited, temp, res);
        return res;
    }

    private void dfs4(int[] nums, boolean[] visited, List<Integer> temp,
            List<List<Integer>> res) {
        if (temp.size() == nums.length) {
            res.add(new ArrayList<Integer>(temp));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (i > 0 && !visited[i - 1] && nums[i] == nums[i - 1]) // 这个非常的重要!!!!!!!!!!
                continue;
            if (!visited[i]) {
                visited[i] = true;
                temp.add(nums[i]);
                dfs4(nums, visited, temp, res);
                temp.remove(temp.size() - 1);
                visited[i] = false;
            }
        }
    }

    /*
     * 46. Permutations 12.13 by Mingyang 方法还是原来那个套路,还是用一个循环递归处理子问题。
     * 区别是这里并不是一直往后推进的,前面的数有可能放到后面,所以我们需要维护一个visited数组来表示该元素是否已经在当前结果中,
     * 因为每次我们取一个元素放入结果,然后递归剩下的元素,所以不会出现重复
     * 这道题还有一个扩展就是如果元素集合中会出现重复,那么意味着我们需要跳过一些重复元素
     */
    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        if (nums == null || nums.length == 0)
            return res;
        boolean[] visited = new boolean[nums.length];
        List<Integer> temp = new ArrayList<Integer>();
        dfs3(nums, visited, temp, res);
        return res;
    }

    private void dfs3(int[] nums, boolean[] visited, List<Integer> temp,
            List<List<Integer>> res) {
        if (temp.size() == nums.length) {
            res.add(new ArrayList<Integer>(temp));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (!visited[i]) {
                visited[i] = true;
                temp.add(nums[i]);
                dfs3(nums, visited, temp, res);
                temp.remove(temp.size() - 1);
                visited[i] = false;
            }
        }
    }

    /*
     * combinationSum III 12.18 by Mingyang
     * 两个地方需要注意,第一个是++start,因为你进入下一个dfs的时候,需要考虑加一个
     * ,但是如果你是start++就会先传递start进去后面再加,这样就不行
     * 另外一个就是i一定要取到9,虽然大小聪明,想只取到7,但是后面的遍历可能也会遍历到9啊。
     */
    public List<List<Integer>> combinationSum3(int k, int n) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        List<Integer> temp = new ArrayList<Integer>();
        dfs(res, temp, k, n, 1);
        return res;
    }

    public void dfs(List<List<Integer>> res, List<Integer> temp, int k, int n,
            int start) {
        if (k == 0) {
            if (n == 0) {
                res.add(new ArrayList<Integer>(temp));
            }
            return;
        }
        for (int i = start; i <= 9; i++) {
            temp.add(i);
            dfs(res, temp, k - 1, n - i, ++start);
            temp.remove(temp.size() - 1);
        }
    }

    /*
     * Combination Sum II 12.13 by Mingyang Each number in C may only be used
     * once in the combination.
     * 在这里我们还是需要在每一次for循环前做一次判断,因为虽然一个元素不可以重复使用,但是如果这个元素重复出现是允许的,
     * 但是为了避免出现重复的结果集,我们只对于第一次得到这个数进行递归,接下来就跳过这个元素了,
     * 因为接下来的情况会在上一层的递归函数被考虑到,这样就可以避免重复元素的出现。 Each number in C may only be used
     * once in the combination. I 是The same repeated number may be chosen from C
     * unlimited number of times.
     */
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        List<Integer> temp = new ArrayList<Integer>();
        if (candidates == null || candidates.length == 0)
            return res;
        Arrays.sort(candidates);
        dfs2(candidates, target, 0, temp, res);
        return res;
    }

    public void dfs2(int[] candidates, int remain, int begin,
            List<Integer> temp, List<List<Integer>> res) {
        if (remain == 0) {
            res.add(new ArrayList<Integer>(temp));
            return;
        }
        if (remain < 0)
            return;
        for (int i = begin; i < candidates.length; i++) {
            if (i > begin && candidates[i] == candidates[i - 1])
                continue;
            temp.add(candidates[i]);
            dfs2(candidates, remain - candidates[i], i + 1, temp, res);
            temp.remove(temp.size() - 1);
        }
    }

    /*
     * Combination Sum 12.13 by Mingyang The same repeated number may be chosen
     * from C unlimited number of times.
     * 注意在实现中for循环中第一步有一个判断,那个是为了去除重复元素产生重复结果的影响
     * 因为在这里每个数可以重复使用,所以重复的元素也就没有作用了,所以应该跳过那层递归。
     */
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        List<Integer> temp = new ArrayList<Integer>();
        if (candidates == null || candidates.length == 0)
            return res;
        Arrays.sort(candidates);
        dfs(candidates, target, 0, temp, res);
        return res;
    }

    public void dfs(int[] candidates, int remain, int begin,
            List<Integer> temp, List<List<Integer>> res) {
        if (remain == 0) {
            res.add(new ArrayList<Integer>(temp));
            return;
        }
        if (remain < 0)
            return;
        for (int i = begin; i < candidates.length; i++) {
            if (i > 0 && candidates[i] == candidates[i - 1]) // 这里就是跳过那个重复的元素,因为每次已经可以重复使用自己了
                continue;
            temp.add(candidates[i]);
            dfs(candidates, remain - candidates[i], i, temp, res);
            temp.remove(temp.size() - 1);
        }
    }
    /*
     * 22. Generate Parentheses 12.13 by Mingyang
     */
    public static List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<String>();
        if (n <= 0)
            return res;
        StringBuffer sb = new StringBuffer();
        dfs100(n, n, res, sb);
        return res;
    }

    public static void dfs100(int left, int right, List<String> res,
            StringBuffer sb) {
        if (left == 0 && right == 0) {
            res.add(sb.toString());
            System.out.println(sb.toString());
            return;
        }
        if (left > right)
            return;
        if (left < 0 || right < 0)
            return;
        sb.append(‘(‘);
        dfs100(left - 1, right, res, sb);
        sb.deleteCharAt(sb.length() - 1);
        sb.append(‘)‘);
        dfs100(left, right - 1, res, sb);
        sb.deleteCharAt(sb.length() - 1);
    }

    /*
     * Simplify Path 12.3 by Mingyang 当遇到“/../"则需要返回上级目录,需检查上级目录是否为空。
     *
     * 当遇到"/./"则表示是本级目录,无需做任何特殊操作。
     *
     * 当遇到"//"则表示是本级目录,无需做任何操作。
     *
     * 当遇到其他字符则表示是文件夹名,无需简化。
     *
     * 当字符串是空或者遇到”/../”,则需要返回一个"/"。
     *
     * 当遇见"/a//b",则需要简化为"/a/b"。 所以我们这里遇到简化的时候,先split为//之间的值。然后用两个堆栈来解决,因为方向是反的
     * 当字符串为空或者为".",不做任何操作。
     *
     * 当字符串不为"..",则将字符串入栈。
     *
     * 当字符串为"..", 则弹栈(返回上级目录)。
     */
    public String simplifyPath(String path) {
        if (path == null || path.length() == 0)
            return path;

        Stack<String> stack = new Stack<String>();
        String[] list = path.split("/");

        for (int i = 0; i < list.length; i++) {
            if (list[i].equals(".") || list[i].length() == 0)
                continue;
            else if (!list[i].equals(".."))
                stack.push(list[i]);
            else {
                if (!stack.isEmpty())
                    stack.pop();
            }
        }

        StringBuilder res = new StringBuilder();

        Stack<String> temp = new Stack<String>();
        while (!stack.isEmpty())
            temp.push(stack.pop());

        while (!temp.isEmpty())
            res.append("/" + temp.pop());

        if (res.length() == 0)
            res.append("/");

        return res.toString();
    }
    /*
     * 17. Letter Combinations of a Phone Number
     * 11.30 by Mingyang 是对keyboard的循环
     */
    public List<String> letterCombinations(String digits) {
        List<String> result = new ArrayList<String>();
        if (digits == null || digits.length() == 0)
            return result;
        String[] keyboard = { "", "", "abc", "def", "ghi", "jkl", "mno","pqrs", "tuv", "wxyz" };
        StringBuilder current = new StringBuilder();
        int index = 0;
        dfs(digits, index, current, keyboard, result);
        return result;
    }
    private void dfs(String digits, int index, StringBuilder current,String[] keyboard, List<String> result) {
        if (index == digits.length()) {
            result.add(current.toString());
            return;
        }
        int num = digits.charAt(index) - ‘0‘;// get integer number
        for (int i = 0; i < keyboard[num].length(); i++) {
            current.append(keyboard[num].charAt(i));
            dfs(digits, index + 1, current, keyboard, result);
            current.deleteCharAt(current.length() - 1);
        }
    }
    /*
     * Additive Number 1.2 by Mingyang
     */
    public boolean isAdditiveNumber(String s) {
        int n = s.length();
        for (int i = 1; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                long a = parse(s.substring(0, i));
                long b = parse(s.substring(i, j));
                if (a == -1 || b == -1)
                    continue;
                if (dfs(s.substring(j), a, b))
                    return true;
            }
        }
        return false;
    }

    boolean dfs(String s, long a, long b) {
        if (s.length() == 0)
            return true;

        for (int i = 1; i <= s.length(); i++) {
            long c = parse(s.substring(0, i));
            if (c == -1)
                continue;
            if (c - a == b && dfs(s.substring(i), b, c)) {
                return true;
            }
        }
        return false;
    }

    long parse(String s) {
        if (!s.equals("0") && s.startsWith("0"))
            return -1;
        long result = 0;
        try {
            result = Long.parseLong(s);
        } catch (NumberFormatException e) {
            return -1;
        }
        return result;
    }
}
时间: 2024-11-13 20:25:24

Leetcode总结之Backtracking的相关文章

【Leetcode】Combinations (Backtracking)

Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For example, If n = 4 and k = 2, a solution is: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ] 这是一道经典的NP问题,采用回朔法 i从1开始, 先加入1,再加入2 temp=[1,2] 然后去掉2 加3 temp=[1,3]

Leetcode 78. Subsets (backtracking) 90 subset

using prev class Solution { List<List<Integer>> res = new ArrayList<List<Integer>>(); public List<List<Integer>> subsets(int[] nums) { List<Integer> temp = new ArrayList<>(); back(temp,nums, 0); return res;

[Leetcode] Backtracking回溯法解题思路

碎碎念: 最近终于开始刷middle的题了,对于我这个小渣渣确实有点难度,经常一两个小时写出一道题来.在开始写的几道题中,发现大神在discuss中用到回溯法(Backtracking)的概率明显增大.感觉如果要顺利的把题刷下去,必须先要把做的几道题题总结一下. 先放上参考的web: https://segmentfault.com/a/1190000006121957 http://summerisgreen.com/blog/2017-07-07-2017-07-07-算法技巧-backtr

[LeetCode] Backtracking Template for (Subsets, Permutations, and Combination Sum)

根据issac3 用Java总结了backtracking template, 我用他的方法改成了Python. 以下为template. 1 def backtrack(ans, temp, nums, start): # 可能有start, 也可能没有 2 if len(temp) == len(nums): 3 ans.append(temp) 4 else: 5 for i in range(start, len(nums)): 6 if nums[i] not in temp: 7 b

[LeetCode] 90.Subsets II tag: backtracking

Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set). Note: The solution set must not contain duplicate subsets. Example: Input: [1,2,2] Output: [ [2], [1], [1,2,2], [2,2], [1,2], [] ] 这个题目思路

leetcode N-Queens/N-Queens II, backtracking, C++

thanks to the video of stanford cs106b lecture 10 by Julie Zelenski for the nice explanation of recursion and backtracking, highly recommended. //N-Queens(12ms) class Solution { vector<vector<string>> ans; int N; //int numofsol; void AddTo_ans

Leetcode之backtracking

其实backtracking对我来说一直是一个难点.我分析不好,而且脑子会很乱.. 今天遇到了一道题: Generate Parentheses(LC22 medium) Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. For example, given n = 3, a solution set is: [ "((()))"

【LeetCode】回溯法 backtracking(共39题)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica } [10]Regular Expression Matching [17]Letter Combinations of a Phone Number [22]Generate Parentheses (2019年2月13日) 给了一个N,生成N对括号的所有情况的字符串. n = 3 [ "((()))", "(()())", "(

leetcode Ch3-DFS &amp; Backtracking II

一.Gray Code 1 class Solution 2 { 3 public: 4 vector<int> grayCode(int n) 5 { 6 vector<int> result={0}; 7 if(n==0) return result; 8 return dfs(n); 9 } 10 vector<int> dfs(int n) 11 { 12 if(n==1) 13 { 14 vector<int> v={0,1}; 15 return