Leetcode backtracking

17. Letter Combinations of a Phone Number

22. Generate Parentheses

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:

[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]

class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> ans =  new ArrayList<String>();
        String  res = "";
        dfs(0,0, n,res,ans);
        return ans;
    }
    
    private void dfs(int left,int right, int n, String res, List<String> ans)
    {
        if(left==n &&right==n) 
        {
            ans.add(new String(res));
            return;
        }
        
        if (left<n) dfs(left+1, right, n,res+"(",ans);
        
        if (right<left) dfs(left, right+1, n,res+")",ans);
    }
}

39. Combination Sum

Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

The same repeated number may be chosen from candidates unlimited number of times.

Note:

All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.
Example 1:

Input: candidates = [2,3,6,7], target = 7,
A solution set is:
[
[7],
[2,2,3]
]

思路:
注意:
在 循环条件里加入 target >= candidates[i]; 尽早跳出循环

扫描二维码关注公众号,回复: 9005157 查看本文章
  • List item
class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) 
    {
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        List<Integer> res =  new ArrayList<>();
        
        Arrays.sort(candidates);
        int start = 0;
        dfs(start, candidates, target, res, ans);
        return ans;
    }
    
    private void dfs(int start, int[]candidates, int target, List<Integer> res, List<List<Integer>> ans )
    {   
        if(target<0) return;
        if(target==0)
        {
            ans.add(new ArrayList<Integer>(res));
            return;
        }
        
        for(int i= start; i<candidates.length  &&  target >= candidates[i]; i++)
        {
            res.add(candidates[i]);
            dfs(i,candidates, target-candidates[i],res,ans);
            res.remove(res.size()-1);
        }
    }
}

40. Combination Sum II

Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

Each number in candidates may only be used once in the combination.

Note:

All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.
Example 1:

Input: candidates = [10,1,2,7,6,1,5], target = 8,
A solution set is:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]

注意:

  • 在 循环条件里加入 target >= candidates[i]; 尽早跳出循环
  • explore 坐标为 i+1;
class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        List<Integer> res = new ArrayList<Integer>();
        
        Arrays.sort(candidates);
        int start = 0;
        dfs(start, candidates, target, res, ans);
        return ans;
    }
    
    private void dfs(int start, int[] candidates, int target, List<Integer> res,List<List<Integer>> ans)
    {
        if(target<0) return;
        
        if(target == 0)
        {
            ans.add(new ArrayList<Integer> (res));
            return;
        }
        
        for(int i = start; i<candidates.length;i++)
        {   
            if((i>start) && (candidates[i]==candidates[i-1])) continue;
         
            res.add(candidates[i]);
            dfs(i+1, candidates, target-candidates[i], res, ans);
            res.remove(res.size()-1);
        }
    }
}

46. Permutations

Given a collection of distinct integers, return all possible permutations.

Example:

Input: [1,2,3]
Output:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
思路1:
设一组数p = {r1, r2, r3, … ,rn}, 全排列为perm§,pn = p - {rn}。因此perm§ = r1perm(p1), r2perm(p2), r3perm(p3), … , rnperm(pn)。当n = 1时perm(p} = r1。为了更容易理解,将整组数中的所有的数分别与第一个数交换,这样就总是在处理后n-1个数的全排列。

思路2:
这种思路和思路1的区别是:思路1采用位置两两交换,交换后出现一种新的组合,将这种新的组合添加到中间集,再添加到结果集中。而这种思路是采用逐一向中间集添加元素,并将当中间集元素个数等于 nums 长度的时候,将中间集添加到结果集中,并终止该层递归.

class Solution {
    public List<List<Integer>> permute(int[] nums) 
    {
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        List<Integer> res =  new ArrayList<Integer>();     
        for(int n:nums)  res.add(n);  
        
        dfs(0,res,ans);
        return ans;
    }
    
    private void dfs(int swap_times,List<Integer> res, List<List<Integer>> ans )
    {
        if(swap_times == res.size())
        {
            ans.add(new ArrayList<Integer> (res));
            return;
        }
        
        for(int i= swap_times; i<res.size();i++)
           {
              Collections.swap(res,i,swap_times);
              dfs(swap_times+1,res,ans);
              Collections.swap(res,i,swap_times); 
           }
    }
}
class Solution {
    public List<List<Integer>> permute(int[] nums) 
    {
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        List<Integer> res =  new ArrayList<Integer>();      
        boolean [] used = 
        dfs(nums,res,ans);
        return ans;
    }
    
    private void dfs(int[] nums,List<Integer> res, List<List<Integer>> ans )
    {
       if(res.size()==nums.length)
       {
           ans.add(new ArrayList<Integer> (res));
           return;
       }
        
        for(int i=0; i<nums.length; i++)
        {
            if(res.contains(nums[i])) continue;
            res.add(nums[i]);
            dfs(nums,res,ans);
            res.remove(res.size()-1);
        }
    }
}

47. PermutationsII

Given a collection of numbers that might contain duplicates, return all possible unique permutations.
Example:

Input: [1,1,2]
Output:
[
[1,1,2],
[1,2,1],
[2,1,1]
]

class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) 
    {
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        List<Integer> res =  new ArrayList<Integer>();      
        boolean[] used = new boolean[nums.length];
        Arrays.sort(nums);
        
        dfs(used,nums,res,ans);
        return ans;
    }
    
    private void dfs( boolean[] used, int[] nums,List<Integer> res, List<List<Integer>> ans )
    {
       if(res.size()==nums.length)
       {
           ans.add(new ArrayList<Integer> (res));
           return;
       }
        
        for(int i=0; i<nums.length; i++)
        {
            // 被使用过 continue; nums[i] == nums[i-1] 且 前一个相同的没有被使用过continue;
            if(used[i] || i > 0 && nums[i] == nums[i-1] && !used[i - 1]) continue;
            used[i]=true; 
            res.add(nums[i]);
            dfs(used,nums,res,ans);
            res.remove(res.size()-1);
            used[i] = false;

            
        }
    }
}

51. N-Queens

The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.

Given an integer n, return all distinct solutions to the n-queens puzzle.

Each solution contains a distinct board configuration of the n-queens’ placement, where ‘Q’ and ‘.’ both indicate a queen and an empty space respectively.

Input: 4
Output: [
[".Q…", // Solution 1
“…Q”,
“Q…”,
“…Q.”],

["…Q.", // Solution 2
“Q…”,
“…Q”,
“.Q…”]
]

class Solution {
    public List<List<String>> solveNQueens(int n) {
        List<List<String>> ans = new ArrayList<List<String>>();
        char [][] chess = new char[n][n];
        for(int i= 0; i<n;i++){
            for(int j = 0; j<n; j++){
                chess[i][j] = '.';
            }
        }
        
        dfs(0, n, chess, ans);
        return ans;
    }
    
    private void dfs(int row, int n, char[][] chess, List<List<String>> ans)
    {   
        if (row==n)
        {
            ans.add(construct(chess));
            return;
        }
     
        for(int col =0; col<n; col++)
        {
            if(isValid(chess, n, row, col ))
            {
                chess[row][col] = 'Q';
                dfs(row+1,n,chess,ans);
                chess[row][col] = '.';
            }
        }
    }
    
    private boolean isValid(char[][] chess,int n , int row, int col )
    {
        // check row and col
        for(int i=0; i<row; i++)
        {
            if(chess[i][col]=='Q') 
                return false;
        }
        
        // cheack 45 degree
        for(int i = row-1, j = col+1; i>=0&& j<n; i--,j++)
        {
            if(chess[i][j]=='Q') 
                return false;
        }
        
        // cheack 135 degree
        for(int i = row-1, j = col-1; i>=0&& j>=0; i--,j--)
        {
            if(chess[i][j]=='Q') 
                return false;
        }
        
        return true;
    }
    
//     private List<String> construct(char [][] chess)
//     {   
//         List<String> temp = new ArrayList<>();
//         for(int i = 0; i<chess.length; i++)
//         {
//             temp.add(new String(chess[i]));
//         }
//         return temp;
//     }
    
    
}

52. N-Queens II

The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.

Given an integer n, return the number of distinct solutions to the n-queens puzzle.

Example:

Input: 4
Output: 2

class Solution {
    public int totalNQueens(int n) {
        List<Integer> ans = new ArrayList<>();
        char [][] chess = new char[n][n];
        for(int i= 0; i<n;i++){
            for(int j = 0; j<n; j++){
                chess[i][j] = '.';
            }
        }
        
        dfs(0, n, chess, ans);
        return ans.size();
    }
    
    private void dfs(int row, int n, char[][] chess, List<Integer> ans)
    {   
        if (row==n)
        {
            ans.add(1);
            return;
        }
     
        for(int col =0; col<n; col++)
        {
            if(isValid(chess, n, row, col ))
            {
                chess[row][col] = 'Q';
                dfs(row+1,n,chess,ans);
                chess[row][col] = '.';
            }
        }
    }
    
    private boolean isValid(char[][] chess,int n , int row, int col )
    {
        // check row and col
        for(int i=0; i<row; i++)
        {
            if(chess[i][col]=='Q') 
                return false;
        }
        
        // cheack 45 degree
        for(int i = row-1, j = col+1; i>=0&& j<n; i--,j++)
        {
            if(chess[i][j]=='Q') 
                return false;
        }
        
        // cheack 135 degree
        for(int i = row-1, j = col-1; i>=0&& j>=0; i--,j--)
        {
            if(chess[i][j]=='Q') 
                return false;
        }
        
        return true;
    }
}

60. Permutation Sequence

The set [1,2,3,…,n] contains a total of n! unique permutations.

By listing and labeling all of the permutations in order, we get the following sequence for n =3:

“123”
“132”
“213”
“231”
“312”
“321”
Given n and k, return the kth permutation sequence.

Note:

Given n will be between 1 and 9 inclusive.
Given k will be between 1 and n! inclusive.
Example 1:

Input: n = 3, k = 3
Output: “213”

77. Combinations

Given two integers n and k, return all possible combinations of k numbers out of 1 … n.

Example:

Input: n = 4, k = 2
Output:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]

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

78. Subsets

Given a set of distinct integers, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

Example:

Input: nums = [1,2,3]
Output:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        List<Integer> res =  new ArrayList<Integer>();   
        // Arrays.sort(nums);
        dfs(0,nums,res,ans);
        return ans;
    }
    
    private void dfs( int start, int[] nums,List<Integer> res, List<List<Integer>> ans )
    {   
        ans.add(new ArrayList<Integer> (res));
          
        for(int i=start; i<nums.length;i++)
        {
            res.add(nums[i]);
            dfs(i+1,nums,res,ans);
            res.remove(res.size()-1);
        }
    }
}

90. Subsets II

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],
[]
]

class Solution {
    public List<List<Integer>> subsetsWithDup(int[] nums) 
    {
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        List<Integer> res =  new ArrayList<Integer>();  
        boolean[] used = new boolean[nums.length];
        
        Arrays.sort(nums);
        dfs(0,nums,used,res,ans);
        return ans;
    }
    
    private void dfs( int start, int[] nums, boolean[] used, List<Integer> res, List<List<Integer>> ans )
    {   
        ans.add(new ArrayList<Integer> (res));
          
        for(int i=start; i<nums.length;i++)
        {   
            if(used[i]||i>0 && nums[i]==nums[i-1]&&!used[i-1]) continue;
              
            used[i] =true;
            res.add(nums[i]);
            dfs(i+1,nums,used,res,ans);
            res.remove(res.size()-1);
            used[i]=false;
            
            
        }
    }
}

79. Word Search

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where “adjacent” cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

Example:

board =
[
[‘A’,‘B’,‘C’,‘E’],
[‘S’,‘F’,‘C’,‘S’],
[‘A’,‘D’,‘E’,‘E’]
]

Given word = “ABCCED”, return true.
Given word = “SEE”, return true.
Given word = “ABCB”, return false.

class Solution {
    public boolean exist(char[][] board, String word) {
        int m = board.length;
        int n = board[0].length;
        
        boolean[][] visited= new boolean[m][n];
        
        // 找出board中等于String的首字母
        for(int i=0; i<m;i++)
        {
            for(int j=0; j<n;j++)
            {
                if(word.charAt(0) == board[i][j] && dfs(0,i,j,board,word,visited)) 
                    return true; 
            }
        }
        return false;
    }
    
    private boolean dfs(int count, int i, int j, char[][] board, String word,boolean[][] visited)
    {   
        if (count==word.length()) return true;
        
        if(i >= board.length || i < 0 || 
           j >= board[i].length || j < 0 || 
           board[i][j] != word.charAt(count) || 
           visited[i][j])
        {
            return false;
        }
        
        // 依次调用dfs 寻找其上下左右是否与对应的字符相等
        
        visited[i][j] =true;
        
        if(dfs(count+1,i+1,j,board,word,visited)||
           dfs(count+1,i-1,j,board,word,visited)||
           dfs(count+1,i,j-1,board,word,visited)||
           dfs(count+1,i,j+1,board,word,visited))
        {
            return true;
        }
        
        visited[i][j] =false;
    
        return false;
    
    }
    
}

89. Gray Code

The gray code is a binary numeral system where two successive values differ in only one bit.

Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0.

Example 1:

Input: 2
Output: [0,1,3,2]
Explanation:
00 - 0
01 - 1
11 - 3
10 - 2

For a given n, a gray code sequence may not be uniquely defined.
For example, [0,2,3,1] is also a valid gray code sequence.

00 - 0
10 - 2
11 - 3
01 - 1

class Solution {
    public List<Integer> grayCode(int n) {
        List<Integer> res = new ArrayList<>();
        res.add(0);
       
        for(int i=0; i<n;i++)
        {
            int si = res.size();
            for(int j = si-1; j>=0;j--)
            {
                res.add(res.get(j)|1<<i);
            }
        }
        return res;
    }
}

93. Restore IP Addresses

Given a string containing only digits, restore it by returning all possible valid IP address combinations.

Example:

Input: “25525511135”
Output: [“255.255.11.135”, “255.255.111.35”]

class Solution {
    public List<String> restoreIpAddresses(String s) {
        List<String> result = new ArrayList<>();
        doRestore(result, "", s, 0);
        return result;
    }
    
    private void doRestore(List<String> result, String path, String s, int k) {
        if ( s.isEmpty()||k == 4) {
            if (s.isEmpty()&&k==4)
                result.add(path.substring(1));
            return;
        }
        for (int i = 1; i <= (s.charAt(0) == '0' ? 1 : 3) && i <= s.length(); i++) { // Avoid leading 0 
            // Avoid leading 0
            String part = s.substring(0, i);
            if (Integer.valueOf(part) <= 255)
                doRestore(result, path + "." + part, s.substring(i), k + 1);
        }
    }
}
发布了12 篇原创文章 · 获赞 0 · 访问量 893

猜你喜欢

转载自blog.csdn.net/EPFL_Panda/article/details/100826590