[White] Day2 Brooms question of backtracking summary (dfs)

Preface: backtracking and dynamic programming should be the largest study of two types of algorithms, reference " from" permutation problem "understanding" backtracking search "(DFS + reset state), bit mask techniques, recursive exchange " to do a wrap-up

 

No. 46 force buckle full array


 

Backtracking to solve the problem, my experience is certainly not lazy, pick up the pen and paper, the recursive structure of the problem drawn, in general, is a tree structure, so that the ideas and the code will be more clear. And write code that is the map drawn by the code shown.

Method: "backtracking search" algorithm or "depth-first traversal + + prune reset state" (This question is no pruning)

Input of example: [1, 2, 3]for example, as a permutation problem, as long as we select numbers in order to ensure that the upper layer is selected from the lower layer through the figures do not occur, can be obtained without the weight of all permutations does not leak .

Tree structure as shown in FIG.

 

 Note:

1, especially here point out: Although my chart is showing up all of a sudden, but I think you should draw the diagram is drawn out layer by layer;

2, at every level, we have several pieces branch for us to choose. Number of branches of the next layer on a layer of less than 1, because each layer will schedule a number, from this perspective, why should again be understood that additional space that recording elements used;

3, all of the "arrangement" n are all leaf nodes in the tree recursive tree.

We top this matter to a formal description: solution space problem is a recursive tree, solving process is the recursive tree search for answers in the tree, and the path search is the "depth-first traversal," it's It characterized by "do not hit the brick wall does not look back."

When the program execution to the top of the tree leaf node, then recursively in the end, the current root to leaf node path traveled constitutes a full array, add it to the result set, I take a step termed as a " settlement ."

At this recursive method to return, and for the later method returns, to do two things:

(1) occupies the last release of a number;
(2) ejected from the last number in the currently selected alignment.

In fact finished in each layer method, when about to return are required to do so. This tree each node will be visited twice, once around the node back to the 1st, 2nd back to the node "state" for the first time and came to the node when the "state" of the same, the operation of such programmer attached to the program called " state reset ."

Reset state "is" backtracking "an important operation," backtracking search "is the direction of the search, otherwise we write multiple loops, the amount of code uncontrollable.

Description:

1, the array index i is used is recorded in a recursive process are ever used, a hash table may also be used, in place of the bitmap, in the following reference codes 2 and 3, respectively, provide reference code Java code;

2, when the program went to the first time when a node, said it was considering a number of times to have it added to the list, after deeper recursive back to this node, you need to "reset state", "restore scene" before considering the need to put that number from the end of the pop-up, this is a list at the end of the operation, the most appropriate data structure is the stack (stack).

Solution class: 

    DEF permute (Self, the nums): 
        IF len (the nums) == 0: 
            return [] 

        Used = [False] * len (the nums) 
        RES = [] 
        Self .__ DFS (the nums, 0, [], Used, RES) 
        return RES 

    DEF __dfs (Self, nums, index, pre, Used, RES): 
        # the first to write a recursive termination condition 
        IF index == len (nums): 
            res.append (pre.copy ()) 
            return 

        for i in the Range (len (the nums)): 
            IF not used [I]: 
                # if not used, it is used 
                used [I] = True 
                pre.append (the nums [I]) 

                # DFS before and after, the code is symmetrical
                self.__dfs(nums, index + 1, pre, used, res)

                used[i] = False
                pre.pop()

 Summary:

can be understood by this example, "back", "reset state" operation algorithm, "back search" = "depth-first traversal + + prune reset state."

1 "depth-first traversal" is "do not hit the brick wall does not look back";

2, turn back time to "reset state", that came back to that place on the "status" and to be the last time same.

3, in the code, is often performed in a layer before and after the recursive form of the code is "symmetry."

 

 

note:

ask: why the code res.append (pre.copy ()):

liweiwei1419 9: This is because Python, Java language "variable object" passed in "a method of mass participation" is quoted, ifres.append(pre)so, theresvariable in the store is in a leaf at the junctionprereference variables, andprevariables after the completion of the final back empty list[], useres.append(pre)you'll see a bunch of empty list.

Thus, it is necessary to use pre[:]a slice operation, to obtain a copy of, or the use of pre.copy()the method.

This part of the knowledge you can search for "Python parameter passing mechanism" in the network, "value transfer", "passing by reference", "deep copy", "shallow copy", "copy of the list and sliced" and get relevant keywords Know how. Explain this knowledge has been beyond the scope of my abilities.

If I have to explain the wrong place, welcome you pointed out.


Author: liweiwei1419
link: https: //leetcode-cn.com/problems/permutations/solution/hui-su-suan-fa-python-dai-ma-java-dai-ma-by-liweiw/
Source: stay button ( LeetCode)
copyright reserved by the authors. Commercial reprint please contact the author authorized, non-commercial reprint please indicate the source.

 

Stay button No.17 telephone number of letter combinations


class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        if not digits:
            return []
        
        dict1 = {'2':'abc', '3':'def', '4':'ghi', '5':'jkl', '6':'mno', '7':'pqrs', '8':'tuv', "9":'wxyz'}
        
        paths = []
        self.__dfs(paths, [], digits, 0, dict1)
        return paths
    
    def __dfs(self, paths, path, digits, index, dict1):
        if index == len(digits):
            paths.append(''.join(path.copy()))
            return
        
        for i in range(len(dict1[digits[index]])):
            path.append(dict1[digits[index]][i])
            self.__dfs(paths, path, digits, index+1, dict1)
            path.pop()
        

 

 note:

Data path in the list is [ 'a', 'e', ​​'i', ...]

It is necessary to use: paths.append (. '' Join (path.copy ()))

path.copy () Do not forget! ! !

Guess you like

Origin www.cnblogs.com/ACStrive/p/11441816.html