https://leetcode.com/problems/restore-ip-addresses/
Given a string containing only digits, restore it by returning all possible valid IP address combinations.
For example:
Given "25525511135"
,
return ["255.255.11.135", "255.255.111.35"]
. (Order does not matter)
解题思路:
这题看起来,就是在原来的字符串里找位置插入三个“.”,要求分出来的四部分数字满足某些要求。在所有的可能里找出符合要求的,像是一个组合的问题。我们从左至右来看这个问题,先将“.”插入到一个位置,剩下的字符串里,再选择位置插入“.”。这时应该很敏感的能想到是DFS了。所谓数字符合某些要求,就是要求尽早剪枝。
和前面Letter Combinations of a Phone Number或者Word Search等DFS题目相比,这道题略微复杂的地方在于,需要对原字符串进行修改,插入“.”。这时记录、截取长度就需要细心和注意,不能搞错。
代码还是比较清楚的,AC后加入了不少注释,我一直认为可读性大于简洁性,原来其实不是很长。
public class Solution { public List<String> restoreIpAddresses(String s) { List<String> resultList = new LinkedList<String>(); dfs(s, resultList, new StringBuffer(), 1, 0); dfs(s, resultList, new StringBuffer(), 2, 0); dfs(s, resultList, new StringBuffer(), 3, 0); return resultList; } /* 举例 Given "25525511135", return "255.255.11.135" step = 1进入递归,currentResult=255.,currentLength=3 */ public void dfs(String s, List<String> resultList, StringBuffer currentResult, int currentLength, int step){ //已经组成ip地址的长度,要去掉"." int preLength = currentResult.length() - step; //加上currentLength后的长度已经超过了s的长度 if(preLength + currentLength > s.length()){ return; } //上面的例子里currentString=255 String currentString = s.substring(preLength, preLength + currentLength); //每次划分的数字不能大于255 if(Integer.valueOf(currentString) > 255){ return; } //0.0.0.0可以,但是10.01.1.1就不行 if(currentString.length() > 1 && currentString.indexOf("0") == 0){ return; } if(step == 3){ //只有递归到第4步,并且正好将s剩下的字符都用完,才正确 if(preLength + currentLength == s.length()){ //最后一步后面不需要加"."了 currentResult.append(currentString); resultList.add(currentResult.toString()); } //只要到第4步就一定返回了,不会再往下 return; } currentResult.append(currentString); currentResult.append("."); dfs(s, resultList, currentResult, 1, step + 1); dfs(s, resultList, currentResult, 2, step + 1); dfs(s, resultList, currentResult, 3, step + 1); currentResult = currentResult.delete(preLength + step, currentResult.length()); } }
这道题写了6次就写出来了,其中三次是compile error,还有三次是剪枝的不全面。比如0.0.0.0可以,但是10.01.1.1就不行。还有只有递归到第4步,并且正好将s剩下的字符都用完,才正确。