LeetCode's backtracking 1-letter combination of phone number (17), bracket generation (22), recovery of IP address (93)

1. Letter combination of telephone number (17)

Title description:

【medium】

Given a string containing only numbers 2-9 , return all letter combinations it can represent. The answers can be returned in any order.

The mapping of numbers to letters is given as follows (same as phone buttons). Note that 1 does not correspond to any letters.

Insert picture description here
Example 1:

输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]

Topic link

Thinking analysis

1. For "23", it is not difficult to deduce its solution as the following figure:

Insert picture description here

  • This is obviously to find all the solutions of the leaves in the tree structure, and find all the solutions in the tree structure, usually using the backtracking algorithm.

2. First write a one-to-one mapping dictionary of numbers and characters, phone={'number (key)':'corresponding letter (value)'}.

3. In this question, since each letter corresponding to each number may enter a letter combination, there is no infeasible solution, just enumerate all the solutions.

Define the backtracking function:

  • Backtracking exit: If the number of backtracking times is the same as the length of the number string, it is a feasible solution, and it is stored in the result table.
  • Backtracking the main body: do the following for the letter corresponding to the number in each number string:
    • Add it to a list of feasible solutions
    • Backtracking operation for the next character
    • Cancel the mark and return to the state to restore the list of feasible solutions to be empty
class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        if not digits:
            return []
        #定义数字字符映射字典
        phonemap={
    
    
            "2": "abc",
            "3": "def",
            "4": "ghi",
            "5": "jkl",
            "6": "mno",
            "7": "pqrs",
            "8": "tuv",
            "9": "wxyz",
        }
        #存储可行解
        combination=[]
        #存储最终解,集合可行解
        combinations=[]
        #定义回溯函数
        def backtrack(i):
            #回溯出口:满足条件的解
            #如果回溯次数等于数字字符串的长度,就是一个可行解
            if i==len(digits):
                combinations.append("".join(combination))
            #回溯主体
            else:
                digit=digits[i]
                for letter in phonemap[digit]:
                    combination.append(letter)
                    #对数字字符串的下一个数字进行回溯
                    backtrack(i+1)
                    #取消标记,状态返回,不再走这条路
                    combination.pop()#combination再次为空
        backtrack(0)
        return combinations
  • Time complexity: O (3 m + 4 n) O(3^m+4^n)O ( 3m+4n ), where m is the number of digits corresponding to 3 letters in the input, and n is the number of digits corresponding to 4 letters in the input.
  • Space complexity: O (m + n) O(m+n)O ( m+n)

2. Bracket generation (22)

Title description:

[Medium]
digital generation n represents the number of brackets, you design a function to be able to generate all possible and effective brackets combination.

Example 1:

输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

Topic link

Thinking analysis

3. Restore the IP address (93)

Title description:

【medium】

Given a string containing only numbers, restore it and return all possible IP address formats.

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:

输入:s = "25525511135"
输出:["255.255.11.135","255.255.111.35"]

Topic link

Thinking analysis

1. A valid IP address consists of exactly four integers (each integer is between 0 and 255, and cannot contain leading 0), so we can first split with 1, 2, 3 characters and then look at the following Whether it can be satisfied, once the dissatisfaction is found, the road will be blocked. As shown in the figure below:
Insert picture description here
2. Situations that need pruning:

1. At the beginning, the length of the string is less than 4 or greater than 12, and a legal IP address must not be pieced together (this can be generalized to the judgment of the intermediate node to produce pruning behavior);

2. There are only 3 ways to choose interception for each node: cut 1 bit, cut 2 bits, and cut 3 bits. Therefore, each node can grow up to 3 branches at most;

Judging whether it is a reasonable ip segment according to the intercepted string, there are many ways to write it, you can intercept it first, then convert it to int, and then judge. The method I used is to first convert to int, which is a legal ip segment value, and then intercept it.

3. Since the ip segment has 4 segments at most, this trigeminal tree has 4 levels at most, and this condition is used as one of the recursive termination conditions;

4. Each node represents a different stage of solving this problem. The required state variables are:

class Solution:
    def restoreIpAddresses(self, s: str) -> List[str]:
        
        result = []
        def addOnePoint(src, dst, cnt):
            if not src and cnt == 4:
                result.append(dst[:-1])
            if src and cnt < 4:
                for i in range(1, 4):
                    if len(src) >= i and 0 <= int(src[:i]) <= 255 and str(int(src[:i])) == src[:i]:
                        addOnePoint(src[i:], dst + src[:i] + '.', cnt + 1)
        addOnePoint(s, '', 0)
        return result



Guess you like

Origin blog.csdn.net/weixin_45666566/article/details/113800589