Backtrack的经典应用场景.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| class Solution { public List<String> generateDivTags(int numberOfTags) { List<String> result = new ArrayList<>(); StringBuilder currentString = new StringBuilder(); helper(currentString, result, 0, 0, numberOfTags); return result; }
public void helper(StringBuilder currentString, List<String> result, int currentLeftTagNum, int remainingLeftTag, int numberOfTags) { if (currentLeftTagNum == numberOfTags && remainingLeftTag == 0) { result.add(currentString.toString()); return; } if (currentLeftTagNum < numberOfTags) { currentString.append("<div>"); helper(currentString, result, currentLeftTagNum + 1, remainingLeftTag + 1, numberOfTags); currentString.delete(currentString.length() - 5, currentString.length()); }
if (remainingLeftTag > 0) { currentString.append("</div>"); helper(currentString, result, currentLeftTagNum, remainingLeftTag - 1, numberOfTags); currentString.delete(currentString.length() - 6, currentString.length()); } } }
|
像这种只有一个东西来回传来传去(这道题就是那个StringBuilder)的, 我们假设递归函数不会更改它. 也就是传给递归函数一个StringBuilder, 这个递归函数返回的时候还是传进去的样子. 尽管它们中间可能对这个SB进行更改, 但是还给我们的时候还是老样子. 有了这个假设, 我们就按照这个去写逻辑就行了. 第30行加了东西, 进入递归函数假设它不改变我们的SB, 那为了遵守我们的假设我们就得在32行把我们加的东西给删掉. 这样就恢复成了一个原来的样子. 此时再返回就保证了给我们的SB是什么样, 我们还回去还是什么样.
下面这个思路更直观一些. 就是两个变量记录现在还需要多少个左括号和右括号. String的话也不用StringBuilder了, 直接字符串拼接完新的传给下一层就完事儿.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Program {
public ArrayList<String> generateDivTags(int numberOfTags) { ArrayList<String> results = new ArrayList<>(); helper("", numberOfTags, numberOfTags, results); return results; }
public void helper(String currentString, int openNeeded, int closedNeeded, List<String> results) { if (openNeeded == 0 && closedNeeded == 0) { results.add(currentString); return; } if (openNeeded > 0) { String newString = currentString + "<div>"; helper(newString, openNeeded - 1, closedNeeded, results); } if (openNeeded < closedNeeded) { String newString = currentString + "</div>"; helper(newString, openNeeded, closedNeeded - 1, results); } } }
|