97. Interleaving String
Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.
For example,
Given:
s1 = "aabcc"
,
s2 = "dbbca"
,
When s3 = "aadbbcbcac"
, return true.
When s3 = "aadbbbaccc"
, return false.
Solution: 动规,直接深搜会超时。设f(x1,x2)表示s1的前x1位和s2的前x2位能够匹配到s3(即s3的前x1+x2位),则状态转移方程为:
f(x1, x2) = {f(x1-1,x2) && (s3(x1+x2-1) == s1(x1-1))}
|| {f(x1,x2
-1) && (s3(x1+x2-1) == s2(x2-1))};
从此方程可以看出,每一次计算的时候实际只会调用到前一行或前一列的数据而不会调用更早的数据,因此可以使用滚动数组来将内存压缩到O(n)。
Code:
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
if(s3.size()!=s1.size()+s2.size()) return false; //注意特殊情况
vector<bool> f(s1.size()+1, false);
f[0] = true;
for(int t=1; t<=s1.size(); t++){
f[t] = f[t-1] && (s3[t-1]==s1[t-1]);
}
for(int i=1; i<=s2.size(); i++){
f[0] = f[0]&&(s3[i-1]==s2[i-1]);
for(int t=1; t<=s1.size(); t++){
f[t] = (f[t]&&(s3[i+t-1]==s2[i-1])) //s3当前字符匹配到s2的情况
||(f[t-1]&&(s3[i+t-1]==s1[t-1])); //s3当前字符匹配到s1的情况
}
}
return f[s1.size()];
}
};
168. Excel Sheet Column Title
Given a positive integer, return its corresponding column title as appear in an Excel sheet.
For example:
1 -> A 2 -> B 3 -> C ... 26 -> Z 27 -> AA 28 -> AB
Credits:
Special thanks to @ifanchu for adding this problem and creating all test cases.
Solution: 进制转换的问题,但是注意+1的位置容易搞错,因为是从1开始的。倒过来的转换想起来比较简单,从字符串转换成数字:
class Solution {
public:
int titleToNumber(string s) {
int ans = 0;
for(int i=0; s[i]; i++){
ans = ans*26 + s[i]-'A'+1;
}
return ans;
}
};
因此将转换公式倒过来就是s[i] = cur%26 - 1 + 'A'。
Code:
class Solution {
public:
string convertToTitle(int n) {
string ans = "";
while(n>0){
n = n-1;
ans.insert(ans.begin(), n%26+'A');
n = n/26;
}
return ans;
}
};
87. Scramble String
Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively.
Below is one possible representation of s1 = "great"
:
great / \ gr eat / \ / \ g r e at / \ a t
To scramble the string, we may choose any non-leaf node and swap its two children.
For example, if we choose the node "gr"
and swap its two children, it produces a scrambled string "rgeat"
.
rgeat / \ rg eat / \ / \ r g e at / \ a t
We say that "rgeat"
is a scrambled string of "great"
.
Similarly, if we continue to swap the children of nodes "eat"
and "at"
, it produces a scrambled string "rgtae"
.
rgtae / \ rg tae / \ / \ r g ta e / \ t a
We say that "rgtae"
is a scrambled string of "great"
.
Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1.
Solution: 动规。注意:本题每次分割是任意取一个分割点,不一定要选择中点,因此状态转移方程为:
f[n][i][j] = (f[k][i][j] && f[n-k][i+k][j+k]) || (f[k][i][j+n-k] && f[n-k][i+k][j])(k为分割点)
Code:
class Solution {
public:
bool isScramble(string s1, string s2) {
if(s1.size()!=s2.size()) return false;
if(s1.size()==1) return s1[0]==s2[0];
const int N = s1.size();
bool f[N][N][N+1];
fill_n(&f[0][0][0], N*N*(N+1), false);
for(int x1=0; x1<N; x1++){
for(int x2=0; x2<N; x2++){
f[x1][x2][1] = (s1[x1]==s2[x2]);
}
}
for(int n=2; n<=N; n++){
for(int x1=0; x1+n<=N; x1++){
for(int x2=0; x2+n<=N; x2++){
for(int k=1; k<n; k++){
if((f[x1][x2][k] && f[x1+k][x2+k][n-k])
|| (f[x1][x2+(n-k)][k] && f[x1+k][x2][n-k])){
f[x1][x2][n] = true;
break;
}
}
}
}
}
return f[0][0][N];
}
};