当前位置: 代码迷 >> 综合 >> LeetCode 22. 括号生成(回溯 动态规划TODO
  详细解决方案

LeetCode 22. 括号生成(回溯 动态规划TODO

热度:3   发布时间:2024-02-24 00:26:21.0

题目不难,熟悉回溯可以无脑写出代码,但是要优化时间复杂度,需要进一步的工作:

无脑回溯 百分之五

class Solution {private List<String> rs;private char[] c=new char[]{'(',')'};private boolean valid(StringBuilder sb){ArrayDeque<Character> stack=new ArrayDeque<>();for(char cc:sb.toString().toCharArray()){if(cc=='('){stack.push(cc);}else{if(stack.isEmpty()){return false;}else{stack.pop();}}}return stack.isEmpty();}private void helper(int n,int cur,StringBuilder sb){if(cur==n){if(valid(sb)){rs.add(sb.toString());}return;}for(char cc:c){sb.append(cc);helper(n,cur+1,sb);sb.deleteCharAt(sb.length()-1);}}public List<String> generateParenthesis(int n) {rs=new ArrayList<>();helper(2*n,0,new StringBuilder());return rs;}
}```

 

稍微剪枝,如果左括号数量和右括号不等,那么直接false,不需要栈来判断 百分之十二

class Solution {private List<String> rs;private char[] c=new char[]{'(',')'};private int left,right;private boolean valid(StringBuilder sb){if(left!=right){return false;}ArrayDeque<Character> stack=new ArrayDeque<>();for(char cc:sb.toString().toCharArray()){if(cc=='('){stack.push(cc);}else{if(stack.isEmpty()){return false;}else{stack.pop();}}}return stack.isEmpty();}private void helper(int n,int cur,StringBuilder sb){if(cur==n){if(valid(sb)){rs.add(sb.toString());}return;}for(char cc:c){sb.append(cc);if(cc=='('){left++;}else{right++;}helper(n,cur+1,sb);sb.deleteCharAt(sb.length()-1);if(cc=='('){left--;}else{right--;}}}public List<String> generateParenthesis(int n) {rs=new ArrayList<>();helper(2*n,0,new StringBuilder());return rs;}
}```

 

再次剪枝,如果left<right(因为任何位置,左括号都不能少于右括号,因为如果该位置之前右括号更多,那么一定无法配对),或者left>n(左括号数不能大于括号对数),都应该立刻返回

class Solution {private List<String> rs;private char[] c=new char[]{'(',')'};private int left,right;private boolean valid(StringBuilder sb){if(left!=right){return false;}ArrayDeque<Character> stack=new ArrayDeque<>();for(char cc:sb.toString().toCharArray()){if(cc=='('){stack.push(cc);}else{if(stack.isEmpty()){return false;}else{stack.pop();}}}return stack.isEmpty();}private void helper(int n,int cur,StringBuilder sb){if(left<right||left>n/2){return;}if(cur==n){if(valid(sb)){rs.add(sb.toString());}return;}for(char cc:c){sb.append(cc);if(cc=='('){left++;}else{right++;}helper(n,cur+1,sb);sb.deleteCharAt(sb.length()-1);if(cc=='('){left--;}else{right--;}}}public List<String> generateParenthesis(int n) {rs=new ArrayList<>();helper(2*n,0,new StringBuilder());return rs;}
}```

发现完全不需要用栈来检测括号,因为只要符合之前提到的两个约束,那么总是valid 1ms

class Solution {private List<String> rs;private char[] c=new char[]{'(',')'};private int left,right;private void helper(int n,int cur,StringBuilder sb){if(left<right||left>n/2){return;}if(cur==n){if(left==right){rs.add(sb.toString());}return;}for(char cc:c){sb.append(cc);if(cc=='('){left++;}else{right++;}helper(n,cur+1,sb);sb.deleteCharAt(sb.length()-1);if(cc=='('){left--;}else{right--;}}}public List<String> generateParenthesis(int n) {rs=new ArrayList<>();helper(2*n,0,new StringBuilder());return rs;}
}```