1.数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例 1:
输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]
示例 2:
输入:n = 1
输出:["()"]
class Solution {
public List<String> res = new ArrayList<>();
public List<String> generateParenthesis(int n) {
dfs(0,0,n,"");
return res;
}
public void dfs(int leftCount,int rightCount,int n,String sum) {
if(leftCount > n || rightCount > n || rightCount > leftCount)
return;
if(leftCount == n && rightCount == n) {
res.add(sum);
return;
}
dfs(leftCount+1,rightCount,n,sum+"(");
dfs(leftCount,rightCount + 1,n,sum + ")");
}
}
2.给定三个字符串 s1、s2、s3,请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。
两个字符串 s 和 t 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串:
s = s1 + s2 + ... + sn
t = t1 + t2 + ... + tm
|n - m| <= 1
交错 是 s1 + t1 + s2 + t2 + s3 + t3 + ... 或者 t1 + s1 + t2 + s2 + t3 + s3 + ...
注意:a + b 意味着字符串 a 和 b 连接。
(1)使用二维数组
class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
int n = s1.length();
int m = s2.length();
int p = s3.length();
if(n + m != p)
return false;
//f[i][j]表示用s1的前i个字符和用s2的前i个字符是否能符合s3的前(i + j - 1)个字符
boolean[][] f = new boolean[n + 1][m + 1];
f[0][0] = true;
for(int i = 0;i <= n;i++) {
for(int j = 0;j <= m;j++) {
int q = i + j - 1;
if(i > 0) {
//f[i][j] = f[i][j] || (f[i - 1][j] && s3.charAt(q) == s1.charAt(i - 1));
//原题是以上的形式,速度慢了一半
//这里的f[i][j] = f[i][j]只是因为j要从0开始,告诉j我i能满足,已经不需要你了
f[i][j] = (f[i - 1][j] && s3.charAt(q) == s1.charAt(i - 1));
}
if(j > 0) {
f[i][j] = f[i][j] || (f[i][j - 1] && s2.charAt(j - 1) == s3.charAt(q));
}
}
}
return f[n][m];
}
}
(2)使用一维数组进行优化
class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
int n = s1.length(), m = s2.length(), t = s3.length();
if (n + m != t) {
return false;
}
boolean[] f = new boolean[m + 1];
f[0] = true;
for (int i = 0; i <= n; ++i) {
for (int j = 0; j <= m; ++j) {
int p = i + j - 1;
if (i > 0) {
f[j] = f[j] && s1.charAt(i - 1) == s3.charAt(p);
}
if (j > 0) {
f[j] = f[j] || (f[j - 1] && s2.charAt(j - 1) == s3.charAt(p));
}
}
}
return f[m];
}
}
(3)动态规划模板
class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
if(s1 == null || s2 == null || s3 == null)
return false;
char[] a = s1.toCharArray();
char[] b = s2.toCharArray();
char[] c = s3.toCharArray();
if(s1.length() + s2.length() != s3.length())
return false;
boolean[][] dp = new boolean[s1.length() + 1][s2.length() + 1];
dp[0][0] = true;
for(int i = 1;i <= s1.length();i++) {
if(s1.charAt(i - 1) != s3.charAt(i - 1))
break;
dp[i][0] = true;
}
for(int i = 1;i <= s2.length();i++) {
if(s2.charAt(i - 1) != s3.charAt(i - 1))
break;
dp[0][i] = true;
}
for(int i = 1;i <= s1.length();i++) {
for(int j = 1;j <= s2.length();j++) {
if((a[i - 1] == c[i + j - 1] && dp[i -1][j]) || (b[j - 1] == c[i + j - 1] && dp[i][j - 1])) {
dp[i][j] = true;
}
}
}
return dp[s1.length()][s2.length()];
}
}