Leetcode Backtracking 回溯法

1079. Letter Tile Possibilities

You have a set of tiles, where each tile has one letter tiles[i] printed on it.  Return the number of possible non-empty sequences of letters you can make.

Example 1:

Input: "AAB"
Output: 8
Explanation: The possible sequences are "A", "B", "AA", "AB", "BA", "AAB", "ABA", "BAA".

Note:

  1. 1 <= tiles.length <= 7
  2. tiles consists of uppercase English letters.

1. Set

class Solution {
    
    public int numTilePossibilities(String tiles) {
        Set<String> set = new HashSet<>();
        int[] visited = new int[tiles.length()];
        StringBuffer substring = new StringBuffer();
        backtrace(tiles, visited, set, substring, 0);
        return set.size();
    }
    
    public void backtrace(String tiles, int[] visited, Set<String> set, StringBuffer substring, int start) {
        if (substring.length() != 0) {
            set.add(substring.toString());
        }
        
        for (int i = 0; i < tiles.length(); i++) {
            if (visited[i] == 0) {
                visited[i] = 1;
                substring.append(tiles.charAt(i));
                backtrace(tiles, visited, set, substring, start + 1);
                visited[i] = 0;
                substring.deleteCharAt(substring.length() - 1);
            }
        }
        return;
    }
}

2. Map

class Solution {
    
    //second 
    int count = -1;
    public int numTilePossibilities(String tiles) {
        Map<Character, Integer> map = new HashMap<>();

        for (char tile : tiles.toCharArray()) {
            map.put(tile, map.getOrDefault(tile, 0) + 1);
        }
        permutation(map.values().toArray(new Integer[map.size()]));
        return count;
    }
    
    public void permutation(Integer[] freq) {
        count++;
        for (int i = 0; i < freq.length; i++) {
            if (freq[i] > 0) {
                freq[i]--;
                permutation(freq);
                freq[i]++;
            }
        }
    }
}

1286. Iterator for Combination

Design an Iterator class, which has:

  • A constructor that takes a string characters of sorted distinct lowercase English letters and a number combinationLength as arguments.
  • A function next() that returns the next combination of length combinationLength in lexicographical order.
  • A function hasNext() that returns True if and only if there exists a next combination.

Example:

CombinationIterator iterator = new CombinationIterator("abc", 2); // creates the iterator.

iterator.next(); // returns "ab"
iterator.hasNext(); // returns true
iterator.next(); // returns "ac"
iterator.hasNext(); // returns true
iterator.next(); // returns "bc"
iterator.hasNext(); // returns false

Constraints:

  • 1 <= combinationLength <= characters.length <= 15
  • There will be at most 10^4 function calls per test.
  • It's guaranteed that all calls of the function next are valid.
class CombinationIterator {

    List<String> combination = new ArrayList<>();
    int cur = 0;
    int len = 0;
    public CombinationIterator(String characters, int combinationLength) {
        char[] ch = characters.toCharArray();
        backtrack(ch, combination, "", 0, combinationLength);
        Collections.sort(combination);
        len = combination.size();
    }
    
    public String next() {
        if (cur + 1 > len) {
            return "";
        }
        else {
            return combination.get(cur++);
        }
    }
    
    public boolean hasNext() {
        return cur < len;
    }
    
    public void backtrack(char[] ch,  List<String> combination, String temp, int start, int length) {
        
        if (!combination.contains(temp) && temp.length() == length) {
            combination.add(temp);
        }
        
        //从(i = start)开始而非(i = 0)
        for (int i = start; i < ch.length; i++) {
            temp = temp + ch[i];
            //传入(i + 1), 不是(start + 1)
            backtrack(ch, combination, temp, i + 1, length);
            temp = temp.substring(0, temp.length() - 1);
        }
    }
}

/**
 * Your CombinationIterator object will be instantiated and called as such:
 * CombinationIterator obj = new CombinationIterator(characters, combinationLength);
 * String param_1 = obj.next();
 * boolean param_2 = obj.hasNext();
 */

1219. Path with Maximum Gold

In a gold mine grid of size m * n, each cell in this mine has an integer representing the amount of gold in that cell, 0 if it is empty.

Return the maximum amount of gold you can collect under the conditions:

  • Every time you are located in a cell you will collect all the gold in that cell.
  • From your position you can walk one step to the left, right, up or down.
  • You can't visit the same cell more than once.
  • Never visit a cell with 0 gold.
  • You can start and stop collecting gold from any position in the grid that has some gold.

 

Example 1:

Input: grid = [[0,6,0],[5,8,7],[0,9,0]]
Output: 24
Explanation:
[[0,6,0],
 [5,8,7],
 [0,9,0]]
Path to get the maximum gold, 9 -> 8 -> 7.

Constraints:

  • 1 <= grid.length, grid[i].length <= 15
  • 0 <= grid[i][j] <= 100
  • There are at most 25 cells containing gold.
class Solution {
    
    public int getMaximumGold(int[][] grid) {
        int max = 0;
        int[][] visited = new int[grid.length][grid[0].length];
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                max = Math.max(max, path(grid, visited, i, j, 0));
            }
        }
        return max;
    }
    
    public int path(int[][] grid, int[][] visited, int row, int col, int cnt) {
        if (row < 0 || row > grid.length - 1 || col < 0 || col > grid[0].length - 1 || grid[row][col] == 0 || visited[row][col] == 1) {
            return cnt;
        }
        
        int count = 0;
        
        visited[row][col] = 1;
        count = Math.max(count, path(grid, visited, row - 1, col, cnt + grid[row][col]));
        count = Math.max(count, path(grid, visited, row + 1, col, cnt + grid[row][col]));
        count = Math.max(count, path(grid, visited, row, col - 1, cnt + grid[row][col]));
        count = Math.max(count, path(grid, visited, row, col + 1, cnt + grid[row][col]));
        visited[row][col] = 0;
        
        return count;
    }

}

 

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. Backtrack:

class Solution {
    //报错:List<List<Integer>> ans = new ArrayList<ArrayList<Integer>>();
    List<List<Integer>> ans = new ArrayList<>();
    public List<List<Integer>> permute(int[] nums) {
        int[] visited = new int[nums.length];
        List<Integer> list = new ArrayList<>();
        backtrack(nums, visited, list, 0);
        
        return ans;
    }
    
    public void backtrack(int[] nums, int[] visited, List<Integer> list, int cur) {
        if (cur == nums.length) {
            ans.add(new ArrayList<>(list)); //必须要新建列表,ans.add(list);输出数据为空
        }
        
        for (int i = 0; i < nums.length; i++) {
            if (visited[i] == 0) {
                visited[i] = 1;
                list.add(nums[i]);
                backtrack(nums, visited, list, cur + 1);
                visited[i] = 0;
                list.remove(list.size() - 1);
            }
        }
    }
}

2. Recursive, Swap

https://leetcode.com/problems/permutations/discuss/550280/JAVA-3-Approaches.-Simple.-Explained-with-comments

class Solution {

    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> ans = new ArrayList<>();
        if (nums == null || nums.length < 1)
            return ans;
        permutation(nums, 0, ans);
        return ans;
    }
    
    public void permutation(int[] nums, int index, List<List<Integer>> ans) {
        if (index == nums.length) {
            ArrayList<Integer> cur = new ArrayList<>();
            for (int num : nums) {
                cur.add(num);
            }
            ans.add(cur);
        }
        
        for (int i = index; i < nums.length; i++) {
            swap(nums, i, index);
            permutation(nums, index + 1, ans);
            swap(nums, i, index);
        }
        
    }
    
    public void swap(int[] nums, int a, int b) {
        int temp = nums[a];
        nums[a] = nums[b]; 
        nums[b] = temp;
    }
}

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值