Discussion on the idea and source code of restoring IP address
The problem of restoring IP address is shown in the figure below. This problem belongs to the type of string and backtracking. It mainly focuses on the use of backtracking traversal method and the understanding of the characteristics of string itself. In the title of this paper, the author thinks of two methods: direct multiple loop method and backtracking method. The backtracking method is written in Java, while the direct multiple loop method is written in Python. Of course, this may not be the optimal solution. I also hope you guys can give a faster algorithm.
I think this problem can be solved by backtracking. First, judge the length of the string. If it is less than 4 or more than 12, it indicates that it is illegal. It is directly excluded and returned. Then initialize the parameters and queue, and call the backtracking search function. Inside the function, we will judge whether the initial position and the length of the string are equal, and whether the position of the tail is 0. If so, we will directly insert it into the result list and return it, and then start circular traversal. Because there are only three interception methods that can be selected for each node, there are three conditional judgments here, If the initial position is larger than the array length, the loop will be ended directly. If the position of the tail multiplied by 3 is smaller than the value of the array length minus the current position, the loop will be ended. If the result of the verification function is satisfied, the result will be added to the list and the backtracking function will continue to be called, and the last element of the queue will pop up. Within the verification function, the range value and special case value of the IP value itself are verified. Finally, the final result is returned after backtracking traversal. According to this idea, our Java code is as follows:
#Fire breathing dragon and water arrow turtle import java.util.ArrayDeque; import java.util.ArrayList; public class Solution { public List<String> restoreIpAddresses(String s) { int lenNum = s.length(); List<String> resFinal = new ArrayList<>(); if (lenNum < 4 || lenNum > 12) { return resFinal; } int step = 4; Deque<String> queueList = new ArrayDeque<>(step); dfsSearch(s, lenNum, 0, step, queueList, resFinal); return resFinal; } private void dfsSearch(String s, int lenNum, int start, int over, Deque<String> queueList, List<String> resFinal) { if (start == lenNum) { if (over == 0) { resFinal.add(String.join(".", queueList)); } return; } for (int ir = start; ir < start + 3; ir++) { if (ir >= lenNum) { break; } if (over * 3 < lenNum - ir) { continue; } if (examWord(s, start, ir)) { String rs = s.substring(start, ir + 1); queueList.addLast(rs); dfsSearch(s, lenNum, ir + 1, over - 1, queueList, resFinal); queueList.removeLast(); } } } private boolean examWord(String s, int begin, int end) { int lenNum = end - begin + 1; if (lenNum > 1 && s.charAt(begin) == '0') { return false; } int flag = 0; while (begin <= end) { flag = flag * 10 + s.charAt(begin) - '0'; begin = begin + 1; } return flag >= 0 && flag <= 255; } }
Obviously, we can see that the effect of backtracking method is good, and we can also use the method of direct multiple traversal search for processing. First, define a function to judge whether the string length is 1 or 2 or 3, then define parameters and initialization list, and start the triple for loop traversal operation. If the subscript of the innermost loop is greater than the string length, directly terminate the loop. Otherwise, call the inspection function for segmented comparison. Only when the results of each part meet the conditions, To insert the results into the list and finally return the results. So it can be solved according to this idea. Here is the Python code:
#Fire breathing dragon and water arrow turtle class Solution: def restoreIpAddresses(self, s: str) -> List[str]: def examWord(word: str) -> bool: n = len(word) if(n == 1): return True if(n == 2): return int(word[0]) > 0 if(n == 3): if(int(word[0]) > 0): return int(word)<= 255 return False step = 4 resFinal = [] for ir in range(1,step): for jr in range(ir+1,ir+step): for kr in range(jr+1,jr+step): if(kr >= len(s)): break if examWord(s[:ir]) and examWord(s[ir:jr]) and examWord(s[jr:kr]) and examWord(s[kr:]): resFinal.append(s[:ir] + "." + s[ir:jr] + "." + s[jr:kr] + "." + s[kr:]) return resFinal
As a result, the efficiency of the Java version of the backtracking method is good, while the Python version of the direct multiple traversal method is average, but there should be more methods to further speed up. I hope friends can give me more advice. Thank you very much.