力扣面试150题--括号生成
Day 73
题目描述
思路
初次思路:
代码分为两个部分
第一个部分,获取不重复的括号组合
第二个部分,判断这个组合是否合法
第二部分式常见题 这里不赘述了,以下说明如何获取不重复的括号组合
- 使用first和end来记录左括号和右括号的数量
- back函数中,如果左右括号剩余数量都为0说明得到一个括号组合
- 这里确保不重复起始很简单,对于每一个空格 可能会有左右括号两种情况,就是用回溯即可,因为左右括号数量有限,这样做不会出现重复。(不知道咋说 可以自己画图理解下)
class Solution {public List<String> generateParenthesis(int n) {StringBuilder x=new StringBuilder();char[]kuo=new char[]{'(',')'};List<String>res=new ArrayList<>();back(n,n,x,kuo,res);return res;}public void back(int first,int end,StringBuilder x,char[]kuo,List<String> res){if(first==0&&end==0){if(pan(x)){//合法res.add(x.toString());}return;}if(first>0){x.append('(');first--;back(first,end,x,kuo,res);x.deleteCharAt(x.length()-1);first++;}if(end>0) {x.append(')');end--;back( first, end, x, kuo, res);x.deleteCharAt(x.length() - 1);end++;}}public boolean pan(StringBuilder x) {Stack<Character>stack=new Stack<>();for(int i=0;i<x.length();i++){if(x.charAt(i)=='('){stack.push(x.charAt(i));}else if(x.charAt(i)==')'){if(stack.isEmpty()){return false;}else if(stack.peek()=='('){stack.pop();}else{return false;}}}return stack.isEmpty();}
}
优化思路:提交后发现时间复杂度很高 ,就去翻题解了
发现不需要专门判断括号的合法性,有直接获取合法括号组合的做法见下:
相较上面的代码,有一处变化,即为添加右括号时,只有在右括号剩余数量大于左括号时才添加,仔细思考一下,如果不在这种情况下添加右括号会有以下两种情况:
- 左右括号剩余数量相同时,即为在此之前括号都是合法的,此时添加一个)肯定不合法,因为)必须出现在(后 如()())
- 左括号数量大于右括号,这种情况就更好理解了 不赘述了
class Solution {public List<String> generateParenthesis(int n) {StringBuilder x=new StringBuilder();char[]kuo=new char[]{'(',')'};List<String>res=new ArrayList<>();back(n,n,x,kuo,res);return res;}public void back(int first,int end,StringBuilder x,char[]kuo,List<String> res){if(first==0&&end==0){res.add(x.toString());return;}if(first>0){x.append('(');first--;back(first,end,x,kuo,res);x.deleteCharAt(x.length()-1);first++;}if(end>first) {x.append(')');end--;back( first, end, x, kuo, res);x.deleteCharAt(x.length() - 1);end++;}}
}