Algorithm-Backtracking problem solving framework

1. Introduction to backtracking issues

The backtracking problem is the traversal process of the decision tree. The backtracking problem needs to consider the following questions

  • Path: The choice that has been made, that is, the path from the root node to the current node

  • Selection list: What other choices can be made in the current situation, that is, continue to traverse the nodes and which paths can be taken

  • End condition: reach the leaf node of the decision tree, or stop if the condition is not met

2. Backtracking problem framework

After understanding several issues of the backtracking problem, let's look at the basic framework of backtracking

List<String> result = new ArrayList<String>();
public void backtrack(已经选择的路径,可以做选择的列表) {
  if (满足结束条件)
    result.add(已经选择的路径);
    return;

   for 选择 in 可以做选择的列表 {
     选择列表.remove(选择);
     已经选择的路径.add(选择);
     backtrack(已经选择路径,可以做选择的路径);

     //撤销
     已经选择的路径.remove(选择);
     可以做选择的列表.add(选择);
   }
} 

3. Case

Optics don't practice fake handles. Before seeing the idea, write it yourself and see if there is any improvement.

3.1 Full array of strings

Given a no repeat sequence of numbers, it returns all possible full array. Source: https://leetcode-cn.com/problems/permutations/

Example:

//输入: [1,2,3]
//输出:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]
class Solution {

    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        int[] visited = new int[nums.length];
        backtrack(res, nums, new ArrayList<Integer>(), visited);
        return res;

    }

    private void backtrack(List<List<Integer>> res, int[] nums, ArrayList<Integer> tmp, int[] visited) {
        if (tmp.size() == nums.length) {
            res.add(new ArrayList<>(tmp));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (visited[i] == 1) continue;
            visited[i] = 1;
            tmp.add(nums[i]);
            backtrack(res, nums, tmp, visited);
            visited[i] = 0;
            tmp.remove(tmp.size() - 1);
        }
    }
}

Note : where resis the overall return, tmp is a node on the current path, visitedand numsto identify what are the current node can access

3.2 Legal IP address

Given a string containing only numbers, restore it and return all possible IP address formats. Source: https://leetcode-cn.com/problems/restore-ip-addresses/

A valid IP address consists of exactly four integers (each integer is between 0 and 255, and cannot contain leading 0), and the integers are separated by'.'.

For example: "0.1.2.201" and "192.168.1.1" are valid IP addresses, but "0.011.255.245", "192.168.1.312" and "[email protected]" are invalid IP addresses.

Example 1:

Input: s = "25525511135" Output: ["255.255.11.135","255.255.111.35"] Example 2:

Input: s = "0000" Output: ["0.0.0.0"] Example 3:

Input: s = "1111" Output: ["1.1.1.1"] Example 4:

Input: s = "010010" Output: ["0.10.0.10","0.100.1.0"] Example 5:

输入:s = "101023" 输出:["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]

Solve the code

class Solution {
    public List<String> restoreIpAddresses(String s) {
        List<String> res = new ArrayList();
        List<String> temp = new ArrayList();
        helper(res,temp,s);
        return res;
    }

    void helper(List<String> res,List<String> temp,String next) {
        if(temp.size() > 4) {
            return;
        }
        if(temp.size() == 4 && next.length() == 0) {
            String ip = temp.get(0) + "." + temp.get(1) + "." + temp.get(2) + "." + temp.get(3);
            res.add(ip);
            return;
        }
        for(int i = 0; i < next.length(); i++) {
            String s = next.substring(0,i+1);
            if(s.length() > 1 && s.charAt(0) == '0') {
                continue;
            } 
            if(s.length() > 3) {
                continue;
            }
            if(s.length() == 3 && "255".compareTo(s) < 0) {
                continue;
            }
            temp.add(s);
            helper(res,temp,next.substring(i+1));
            temp.remove(temp.size() - 1);
        }
    }
}

Note : The overall framework still adopts the above structure, but when judging whether the current node should be added to temp, a slightly more complicated judgment must be made. Please pay attention to morefile

Guess you like

Origin blog.csdn.net/hu_lichao/article/details/112145591
Recommended