5469. K 次操作转变字符串
题目描述:
给你两个字符串 s
和t
,你的目标是在k
次操作以内把字符串s
转变成t
。
在第 i 次操作时(1 <= i <= k)
,你可以选择进行如下操作:
选择字符串 s 中满足1 <= j <= s.length
且之前未被选过的任意下标 j (下标从 1 开始),并将此位置的字符切换 i 次。
不进行任何操作。
切换 1 次字符的意思是用字母表中该字母的下一个字母替换它(字母表环状接起来,所以'z'
切换后会变成'a'
)。
请记住任意一个下标j
最多只能被操作1
次。
如果在不超过k
次操作内可以把字符串 s
转变成 t
,那么请你返回 true
,否则请你返回false
。
示例 1:
输入:s = "input", t = "ouput", k = 9
输出:true
解释:第 6 次操作时,我们将 'i' 切换 6 次得到 'o' 。第 7 次操作时,我们将 'n' 切换 7 次得到 'u' 。
示例 2:
输入:s = "abc", t = "bcd", k = 10
输出:false
解释:我们需要将每个字符切换 1 次才能得到 t 。我们可以在第 1 次操作时将 'a' 切换成 'b' ,但另外 2 个字母在剩余操作中无法再转变为 t 中对应字母。
示例 3:
输入:s = "aab", t = "bbb", k = 27
输出:true
解释:第 1 次操作时,我们将第一个 'a' 切换 1 次得到 'b' 。在第 27 次操作时,我们将第二个字母 'a' 切换 27 次得到 'b' 。
提示:
1 <= s.length, t.length <= 10^5
0 <= k <= 10^9
s
和t
只包含小写英文字母。
解题思路:
1)、找到 tmp = t[i] - s[i] + 26
之间的差值,如果小于0 +26
; 大于0,则忽略。
2)、当每次计算kvST[tmp]
当出现((kvST[tmp] - 1) * 26 + tmp) > k
的情况说明,在k
的范围内无法达成,s
到t
的转换。
提示:
其实可以将map
换成vector
,因为 bs(t[i] - s[i])
的数字在0 - 25
之间,所以可以vector<int> kvST(26,0)
代替 map<int , int> kvST
;
map<int , int> kvST
的key
作为下标 存储:bs(t[i] - s[i])
, value
存储的是 下标一致的次数 ;
vector<int> kvST(26,0)
将map
中的key
直接省略,对应下标的kvST[i] = value
表示 下标为bs(t[i] - s[i])
的次数为value
;
代码实现:
class Solution {
public:
bool canConvertString(string s, string t, int k) {
if (s.size() != t.size())
return false ;
map<int , int> kvST ;
int i, tmp;
for (i = 0 ; i < s.size() ; i ++)
{
// +26 是因为有的`t[i] - s[i]`
tmp = int(t[i] - s[i]) + 26 ;
tmp = tmp >= 26 ? tmp - 26 : tmp ;
if (tmp == 0)
continue ;
if (kvST.find(tmp) != kvST.end())
kvST[tmp] ++ ;
else
kvST[tmp] = 1 ;
if (((kvST[tmp] - 1) * 26 + tmp) > k)
return false ;
}
return true ;
}
};
复杂度计算:
时间复杂度: O(s.length())
最大需要遍历整个字符串;
空间复杂度: O(1)
;最大是常数个 – 26个;