题目大意:给出一串字符串,只允许且必须交换一次,让其成为合法的括号匹配的字符串。
法一(借鉴):这里交换,换成直接改变,到最后再做处理即可。用flag标记字符串是否合法。遇到'(',则压栈;遇到')',栈非空则退栈,栈空则标记flag为非法,且变为'(',然后压栈。最后判断:如果flag标记合法,则栈空返回yes,栈非空返回no;如果flag标记非法,则栈中元素=2,则返回yes,否则返回no。代码如下:
1 public static void main(String[] args) throws IOException { 2 BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 3 String line = in.readLine(); 4 int t = Integer.parseInt(line); 5 while(t-- != 0) { 6 line = in.readLine(); 7 int len = line.length(); 8 Stack<Character> s = new Stack<Character>(); 9 int pos = 0; 10 boolean flag = false; 11 //“()”这种情况特殊处理 12 if(len == 2 && line.charAt(0) == '(' && line.charAt(1) == ')') { 13 System.out.println("No"); 14 continue; 15 } 16 //遍历字符串 17 for(pos = 0; pos < len; pos++) { 18 //如果是'(',压栈 19 if(line.charAt(pos) == '(') { 20 s.push('('); 21 } 22 //如果是')' 23 else { 24 //如果栈非空,则从中弹出一个'(',匹配。因为每次都只压栈'(',所以弹出的一定是'('。 25 if(!s.isEmpty()) { 26 s.pop(); 27 } 28 //如果栈空,则出现非法匹配,记录以下,并压栈'(',表示将')'变成'('。 29 //这里其实就是利用变换,而不是交换,来确定。 30 else { 31 flag = true; 32 s.push('('); 33 } 34 } 35 } 36 if(pos == len) { 37 //如果字符串完全括号匹配 38 if(!flag) { 39 //如果栈空,则说明完全匹配 40 if(s.isEmpty()) { 41 System.out.println("Yes"); 42 } 43 //如果非空,则说明不能交换形成括号匹配 44 else { 45 System.out.println("No"); 46 } 47 } 48 //如果字符串非法 49 else { 50 //如果最后栈里不是两个字符,则说明不能交换形成括号匹配, 51 if(s.size() != 2) { 52 System.out.println("No"); 53 } 54 //如果最后栈里面只有两个字符'((',则说明可以进行交换一次,变为合法 55 else { 56 System.out.println("Yes"); 57 } 58 } 59 } 60 else { 61 System.out.println("No"); 62 } 63 } 64 }