题目一
题目描述:
给定一个字符串s,请计算输出含有连续两个s作为子串的最短字符串。注意两个s可能有重叠部分。例如,"ababa"含有两个"aba"。
输入描述:
输入包括一个字符串s,字符串长度length(1 ≤ length ≤ 50),s中每个字符都是小写字母。
输出描述:
输出一个字符串,即含有连续两个s作为子串的最短字符串。
示例:
输入
abracadabra
输出
abracadabracada
解题思路:
这个题目是关于KMP算法中求next数组的问题,我们只需求出字符串最后一个字符后一位的next值。这个能算出来这个题目就解决了。
import java.util.Arrays;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String string = scan.nextLine();
System.out.println(Main.shortestRepeatString(string));
}
public static String shortestRepeatString(String str){
int[] next = new int[str.length() + 1];
Arrays.fill(next, 0);
next[0] = -1;
next[1] = 0;
for (int i = 2; i < next.length; i++) {
char pre = str.charAt(i - 1);
int k = next[i - 1];
while (k != -1){
if (str.charAt(k) == pre) {
next[i] = next[i - 1] + 1;
break;
}
k = next[k];
}
}
return str + str.substring(next[str.length()]);
}
}

题目二
题目描述:
合法的括号匹配序列被定义为:
1. 空串""是合法的括号序列。
2. 如果"X"和"Y"是合法的序列,那么"XY"也是一个合法的括号序列。
3. 如果"X"是一个合法的序列,那么"(X)"也是一个合法的括号序列。
4. 每个合法的括号序列都可以由上面的规则生成。
例如"","()","()()()", "(()())","(((())))"都是合法的。 东东现在有一个合法的括号序列s,一次移除操作分为两步:
1. 移除序列s中第一个左括号。
2. 移除序列s中任意一个右括号,保证操作之后s还是一个合法的括号序列。
东东现在想知道使用上述的移除操作有多少种方案可以把序列s变为空。
如果两个方案中有一次移除操作移除的是不同的右括号就认为是不同的方案。
例如: s = "()()()()()",输出1,因为每次都只能选择被移除的左括号所相邻的右括号。
s = "(((())))",输出24,第一次有4种情况,第二次有3种情况,... ,依次类推,4 * 3 * 2 * 1 = 24。
输入描述:
输入包括一行,一个合法的括号序列s,序列长度length(2 ≤ length ≤ 20)。
输出描述:
输出一个整数,表示方案数。
示例:
输入
(((())))
输出
24
解题思路:
从右往左遍历,遇到左括号看左括号右边右括号数量与左括号数量的差,并将这些差乘起来,即为方案数。
具体代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String s = scan.nextLine();
System.out.println(Main.total(s));
}
public static int total(String str) {
if (str == null || str.length() < 2) {
return 0;
}
int count = 0;
int sum = 1;
for (int i = str.length() - 1; i >= 0; i--) {
if (str.charAt(i) == ')') {
count++;
}else {
sum *= count;
count--;
}
}
return sum;
}
}
