LeetCode刷题day022 (Jieky)

LeetCode第22题

/*
Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

For example, given n = 3, a solution set is:
[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]
*/
import java.util.*;

class ParenthesesCount{
     
	String val = "";
	int leftCount = 0;
	int rightCount = 0;
	ParenthesesCount(){
     }
	ParenthesesCount(String str){
     this.val = str;}
}

public class GenerateParentheses{
     
    public static void main(String[] args){
     
        GenerateParentheses gp = new GenerateParentheses();
        List<String>  result = gp.generateParenthesis(3);
        System.out.println(result);
    }

	// 这种递归等效于穷举了各种情况,效率非常低
	// 先决定一对括号,问题就被这对括号划分为两个子问题
	// 子问题同样先决定一对括号,直至子问题可直接解,即n=0
	// n=0,问题可解,那么n=1的子问题就可以解:两个子问题为n=0
	// 以此类推n=2子问题为n=1和n=0 或 n=0和n=1
	public List<String> generateParenthesis(int n) {
     
        List<String> ans = new ArrayList();
        if (n == 0) {
     
            ans.add("");
        } else {
     
            for (int a = 0; a < n; a++)
                for (String left: generateParenthesis(a))
                    for (String right: generateParenthesis(n-1-a))
                        ans.add("(" + left + ")" + right);
        }
        return ans;
	}
	
	public List<String> generateParenthesis03(int n) {
     
		List<String> ans = new ArrayList<String>();
		backtrack(ans, "", 0, 0, n);
		return ans;
	}
	
	//单项递归,没有返回计算的,递归经常不够高效,但是代码简单
	public void backtrack(List<String> ans,String cur,int left,int right,int n){
     
		// 当cur的长度为2*n,终止条件
		if(cur.length() == 2*n){
     
			ans.add(cur);
			return;
		}
		
		if(left < n){
     
			backtrack(ans, cur+"(", left+1, right, n);
		}
		
		if(right < left){
     
			backtrack(ans, cur+")", left, right+1, n);
		}
	}
	
	// 构造一个结构体,记录当前字符串包含的左括号和右括号数
	public List<String> generateParenthesis02(int n) {
     
        String[] parentheses = {
     "(",")"};

        LinkedList<ParenthesesCount> list = new LinkedList<ParenthesesCount>();
        list.add(new ParenthesesCount());
		
		// 3对括号,一共有3*2个字符
        for(int i=0;i<2*n;i++){
     
			// 删除字符个数为i的字符串,i==2表示插入第三个字符,此时删除字符串长度为2的
            while(list.getFirst().val.length() == i){
     
				// 每次都删除第一个字符串
                ParenthesesCount temp = list.removeFirst();
				
				// 左括号数小于n,才能追加左括号
				if(temp.leftCount < n){
     
					ParenthesesCount add = new ParenthesesCount(temp.val + "(");
					add.leftCount = temp.leftCount+1;
					add.rightCount = temp.rightCount;
					list.addLast(add);
				}
				
				// 右括号数小于左括号数,才能追加右括号
				if(temp.rightCount < temp.leftCount){
     
					ParenthesesCount add = new ParenthesesCount(temp.val + ")");
					add.leftCount = temp.leftCount;
					add.rightCount = temp.rightCount+1;
					list.addLast(add);
				}
            }
        }
		
		List<String> ret = new ArrayList<String>();
		for(ParenthesesCount temp:list){
     
			ret.add(temp.val);
		}
		
        return ret;
    }
	
	// 暴力破解,生成所有的字符串可能
    // 将括号加入List的过程中,左括号数大于等于右括号数
    public List<String> generateParenthesis01(int n) {
     
        String[] parentheses = {
     "(",")"};

        LinkedList<String> list = new LinkedList<String>();
        list.add("");
		
		// 3对括号,一共有3*2个字符
        for(int i=0;i<2*n;i++){
     
			// 删除字符个数为i的字符串,i==2表示插入第三个字符,此时删除字符串长度为2的
            while(list.getFirst().length() == i){
     
				// 每次都删除第一个字符串
                String temp = list.removeFirst();
                for(int j=0;j<2;j++){
     
					// 字符串每次都添加到链尾
                    list.addLast(temp+parentheses[j]);
                }
            }
        }
		
		// 挑选出有效的字符串
		List<String> ret = new ArrayList<String>();
		for(String temp:list){
     
			if(isValid(temp)){
     
				ret.add(temp);
			}
		}
		
        return ret;
    }
	
	public boolean isValid(String s){
     
		if(s == null) return false;
		
		if(s != null && s.length() == 0) return true;
		
		HashMap<Character,Character> pairs = new HashMap<Character,Character>(); 
		pairs.put(')','(');
		pairs.put(']','[');
		pairs.put('}','{');
		
		Stack<Character> elements = new Stack<Character>();
		
		// 将字符串转为字符数组
		char[] array = s.toCharArray();
		
		for (int i=0;i<s.length();i++){
     
			char temp = array[i];
			// 左括号入栈
			if (temp == '(' || temp == '{' || temp == '['){
     
				elements.push(temp);
			// 右括号校对栈顶元素是否匹配,匹配则栈顶元素出栈(包装类和基本类型可以自动转换)
			}else if(!elements.empty() && pairs.get(temp) == elements.peek()){
     
				elements.pop();
			// 当前右括号和栈顶元素不匹配,或栈为空且还有右括号
			}else{
     
				return false;
			}
		}
		
		// 查看栈是否为空,栈里面不可能有右括号,主要查看是否还有左括号
		if(elements.empty()){
     
			return true;
		}else{
     
			return false;
		}
	}
}

你可能感兴趣的:(LeetCode,java,leetcode)