class Solution:
def canConvertString(self, s: str, t: str, k: int) -> bool:
if len(s) != len(t):
return False
from collections import Counter
shifts = [0] * 26
for a, b in zip(s, t):
diff = (ord(b) - ord(a)) % 26
if diff != 0:
shifts[diff] += 1
for i in range(1, 26):
# i + 26 * (shifts[i] - 1) must be <= k
if i + 26 * (shifts[i] - 1) > k:
return False
return True
class Solution {
public:
bool canConvertString(string s, string t, int k) {
if (s.length() != t.length()) return false;
vector<int> shifts(26, 0);
for (int i = 0; i < s.length(); ++i) {
int diff = (t[i] - s[i] + 26) % 26;
if (diff != 0) {
shifts[diff]++;
}
}
for (int i = 1; i < 26; ++i) {
if (i + 26 * (shifts[i] - 1) > k) {
return false;
}
}
return true;
}
};
class Solution {
public boolean canConvertString(String s, String t, int k) {
if (s.length() != t.length()) return false;
int[] shifts = new int[26];
for (int i = 0; i < s.length(); ++i) {
int diff = (t.charAt(i) - s.charAt(i) + 26) % 26;
if (diff != 0) {
shifts[diff]++;
}
}
for (int i = 1; i < 26; ++i) {
if (i + 26 * (shifts[i] - 1) > k) {
return false;
}
}
return true;
}
}
var canConvertString = function(s, t, k) {
if (s.length !== t.length) return false;
let shifts = new Array(26).fill(0);
for (let i = 0; i < s.length; ++i) {
let diff = (t.charCodeAt(i) - s.charCodeAt(i) + 26) % 26;
if (diff !== 0) {
shifts[diff]++;
}
}
for (let i = 1; i < 26; ++i) {
if (i + 26 * (shifts[i] - 1) > k) {
return false;
}
}
return true;
};
s
and t
of equal length, and an integer k
, determine if you can convert s
into t
in at most k
moves. In each move, you can choose any character in s
and shift it forward by 1 (from 'a' to 'b', ..., 'z' to 'a'). Each move can only shift one character by one position, and you can apply at most k
moves in total. Each move can be applied to any character, and the same character can be shifted multiple times. You must achieve the exact target string t
after all moves.
s
needs to be shifted a certain number of times to match the corresponding character in t
. The key insight is to count, for each possible shift (from 1 to 25), how many characters need that shift. Since you can only use each move (i.e., each shift amount) once per 26 moves (because after 26 moves, the same character can be shifted again), you need to ensure that for each shift amount, the total number of required moves doesn't exceed what's possible within k
moves.
s
and t
are not equal, immediately return false.s[i]
to t[i]
. The shift is (ord(t[i]) - ord(s[i])) % 26
.i
(from 1 to 25):shifts[i]
times of shift i
. The first can be done at move i
, the next at i + 26
, the next at i + 52
, etc.i + 26 * (shifts[i] - 1)
. If this exceeds k
, it's impossible.k
moves, return true. Otherwise, return false.
Suppose s = "input"
, t = "jovpu"
, k = 20
.
Let's compare each character:
s[0]='i'
to t[0]='j'
: needs 1 shifts[1]='n'
to t[1]='o'
: needs 1 shifts[2]='p'
to t[2]='v'
: needs 6 shiftss[3]='u'
to t[3]='p'
: needs 21 shiftss[4]='t'
to t[4]='u'
: needs 1 shiftk=20
, so it's impossible. The function returns false.
k
. By leveraging modular arithmetic and a fixed-size counter, we avoid brute-force and achieve an efficient solution. The method is elegant because it reduces the problem to simple counting and arithmetic, making it both fast and easy to understand.