题目描述
思路分析:
根据题意,要想使得 LCS 最大,删去任意一个字符即可获得 LCS = |s| - 1 ,再把该字符插到与原来不同的任意位置可以维持原长度,而不影响 LCS 的计算。
因此最暴力的做法是枚举每个字符,把它插入到任意位置,判合法,去重,累计。
优化 1 :插入是插到指定位置的字符之前,如果插入的字符和该位置的字符相同,则插入后还是原字符串,可以跳过这种情况。否则最后的结果要 - 1 。
优化 2 :左右两边一定是左右括号,不用移动它们。但字符却可以插到它们的后面。
判合法:实际上就是括号匹配的平衡性。在这里,如果我们从前到后遍历,左括号可以暂时多于右括号,但不可以少于,因为能够闭合右括号的左括号都在左边,这里其实可以直接通过左括号数是否小于有括号数来判别,英文开始给的序列是合法的,所以左右括号的个数一定是相等的,不用担心左括号数本来就大于右括号的情况。
实例代码:
package com.zhumq.lianxi;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class MatchKuoHao {
//直接使用set来去重
private static Set<String> set = new HashSet<String>();
static int count = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.next();
getSequence(str);
System.out.println(set.size() - 1);
sc.close();
}
private static void getSequence(String str) {
for (int i = 0; i < str.length(); i++) {
StringBuilder sb = new StringBuilder(str);
char c = str.charAt(i);
sb.deleteCharAt(i);
for (int j = 0; j < str.length(); j++) {
sb.insert(j, c);
if (isLegal(sb.toString())) {
set.add(sb.toString());
}
sb.deleteCharAt(j);
}
}
}
private static boolean isLegal(String s) {
int left = 0, right = 0;
//由于左右括号的数目一定相同,可以直接用有括号是否多于左括号来判断是否合法
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(')
left++;
else
right++;
if (right > left)
return false;
}
return true;
}
}