NYOJ 15-括号匹配(二)
15-括号匹配(二)
内存限制:64MB 时间限制:1000ms 特判: No
通过数:91 提交数:276 难度:6
题目描述:
给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
如:
[]是匹配的
([])[]是匹配的
((]是不匹配的
([)]是不匹配的
如:
[]是匹配的
([])[]是匹配的
((]是不匹配的
([)]是不匹配的
输入描述:
第一行输入一个正整数N,表示测试数据组数(N<=10) 每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100
输出描述:
对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。每组测试输出占一行
样例输入:
4 [] ([])[] ((] ([)]
样例输出:
0 0 3 2
参考LeetCode32 longest valid parentheses解法。
利用LeetCode32 longest valid parentheses的方法将字符串去掉所有最完美匹配的子串,假设处理后的子串为stringBuffer。在此串的基础上做会简单很多。
对于没有最完美子串的字符串 s 来说,使用d[i][j]表示子串[i,j)需要最少添加的括号数量。需要注意的是像这样的字符串需要另判断,如(])
状态转移方程为:
1 import java.util.Scanner; 2 3 public class Main{ 4 static class Solution { 5 boolean match(char a, char b) { 6 if (a == '(' && b == ')' || a == '[' && b == ']') 7 return true; 8 return false; 9 } 10 11 public int solve(String s) { 12 if (s.length()<=1) return s.length(); 13 int[][] d = new int[s.length()+1][s.length()+1]; 14 15 for (int i = 0; i < s.length(); i++) { 16 d[i][i] = 0; 17 d[i][i + 1] = 1; 18 } 19 20 for (int step = 2; step <= s.length(); step++) { 21 for (int i = 0; i < s.length() && i+step<s.length()+1; i++) { 22 if (match(s.charAt(i), s.charAt(i + step - 1))) { 23 d[i][i+step]=d[i+1][i+step-1]; 24 }else { 25 int min = 65535; 26 for (int k = i + 1; k < i + step; k++) { 27 min = Math.min(d[i][k] + d[k][i + step], min); 28 } 29 d[i][i + step] = min; 30 } 31 } 32 } 33 return d[0][s.length()]; 34 } 35 } 36 37 public static StringBuffer deSubPerfect(String s) { 38 int[] d = new int[s.length()]; 39 int max = 0; 40 41 for (int i = 1; i < s.length(); i++) { 42 //查找以i位置结尾的最完美匹配 43 int len = 0; 44 if (i-1-d[i-1]>=0 && (s.charAt(i) == ')' && '(' == s.charAt(i - 1 - d[i - 1]) || s.charAt(i)==']' && '['==s.charAt(i-1-d[i-1]))){// (()) 45 len=d[i-1]+2; 46 }else if (!(s.charAt(i)==')' && s.charAt(i-1)=='(') || !(s.charAt(i)==']' && '['==s.charAt(i-1-d[i-1]))){// ()) 47 len=0; 48 }else {// (() || () 49 len = 2; 50 } 51 52 if (i-len>=0 && len!=0){ 53 d[i]=d[i-len]+len; 54 }else { 55 d[i]=len; 56 } 57 max = (max < d[i]) ? d[i] : max; 58 } 59 StringBuffer s1 = new StringBuffer(); 60 for (int i = s.length()-1; i >= 0; i--) { 61 i-=d[i]; 62 if (i>=0) 63 s1.append(s.charAt(i)); 64 } 65 StringBuffer reverse = s1.reverse(); 66 return reverse; 67 } 68 69 public static void main(String[] args) { 70 String s = new String(); 71 Scanner sc = new Scanner(System.in); 72 Solution solution = new Solution(); 73 int n = Integer.parseInt(sc.nextLine()); 74 for (int i = 0; i < n; i++) { 75 s=sc.nextLine(); 76 StringBuffer stringBuffer = deSubPerfect(s); 77 78 int solve = solution.solve(stringBuffer.toString()); 79 System.out.println(solve); 80 } 81 } 82 } 83 //()(]() 84 //(())(())