题目描述
给你一个下标从 0 开始的字符串 str1
和 str2
。
一次操作中,你选择 str1
中的若干下标。对于选中的每一个下标 i
,你将 str1[i]
循环 递增,变成下一个字符。也就是说 'a'
变成 'b'
,'b'
变成 'c'
,以此类推,'z'
变成 'a'
。
如果执行以上操作 至多一次 ,可以让 str2
成为 str1
的子序列,请你返回 true
,否则返回 false
。
注意:一个字符串的子序列指的是从原字符串中删除一些(可以一个字符也不删)字符后,剩下字符按照原本先后顺序组成的新字符串。
示例 1:
输入:str1 = "abc", str2 = "ad"
输出:true
解释:选择 str1 中的下标 2 。
将 str1[2] 循环递增,得到 'd' 。
因此,str1 变成 "abd" 且 str2 现在是一个子序列。所以返回 true 。
示例 2:
输入:str1 = "zc", str2 = "ad"
输出:true
解释:选择 str1 中的下标 0 和 1 。
将 str1[0] 循环递增得到 'a' 。
将 str1[1] 循环递增得到 'd' 。
因此,str1 变成 "ad" 且 str2 现在是一个子序列。所以返回 true 。
示例 3:
输入:str1 = "ab", str2 = "d"
输出:false
解释:这个例子中,没法在执行一次操作的前提下,将 str2 变为 str1 的子序列。
所以返回 false 。
提示:
1 <= str1.length <= 105
1 <= str2.length <= 105
str1
和 str2
只包含小写英文字母。
解法
方法一:双指针
本题实际上需要我们判断一个字符串 $s$ 是否为另一个字符串 $t$ 的子序列,只不过字符之间可以不完全匹配,如果两个字符相同,或者一个字符是另一个字符的下一个字符,就可以匹配。
时间复杂度 $O(m + n)$,其中 $m$ 和 $n$ 分别是字符串 $str1$ 和 $str2$ 的长度。空间复杂度 $O(1)$。
| class Solution:
def canMakeSubsequence(self, str1: str, str2: str) -> bool:
i = 0
for c in str1:
d = "a" if c == "z" else chr(ord(c) + 1)
if i < len(str2) and str2[i] in (c, d):
i += 1
return i == len(str2)
|
1
2
3
4
5
6
7
8
9
10
11
12 | class Solution {
public boolean canMakeSubsequence(String str1, String str2) {
int i = 0, n = str2.length();
for (char c : str1.toCharArray()) {
char d = c == 'z' ? 'a' : (char) (c + 1);
if (i < n && (str2.charAt(i) == c || str2.charAt(i) == d)) {
++i;
}
}
return i == n;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13 | class Solution {
public:
bool canMakeSubsequence(string str1, string str2) {
int i = 0, n = str2.size();
for (char c : str1) {
char d = c == 'z' ? 'a' : c + 1;
if (i < n && (str2[i] == c || str2[i] == d)) {
++i;
}
}
return i == n;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13 | func canMakeSubsequence(str1 string, str2 string) bool {
i, n := 0, len(str2)
for _, c := range str1 {
d := byte('a')
if c != 'z' {
d = byte(c + 1)
}
if i < n && (str2[i] == byte(c) || str2[i] == d) {
i++
}
}
return i == n
}
|
| function canMakeSubsequence(str1: string, str2: string): boolean {
let i = 0;
const n = str2.length;
for (const c of str1) {
const d = c === 'z' ? 'a' : String.fromCharCode(c.charCodeAt(0) + 1);
if (i < n && (str2[i] === c || str2[i] === d)) {
++i;
}
}
return i === n;
}
|