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 //(())(())
 
原文地址:https://www.cnblogs.com/yfs123456/p/10993913.html