一.问题描述
You are given two strings s
and t
of the same length. You want to change s
to t
. Changing the i
-th character of s
to i
-th character of t
costs |s[i] - t[i]|
that is, the absolute difference between the ASCII values of the characters.
You are also given an integer maxCost
.
Return the maximum length of a substring of s
that can be changed to be the same as the corresponding substring of t
with a cost less than or equal to maxCost
.
If there is no substring from s
that can be changed to its corresponding substring from t
, return 0
.
Example 1:
Input: s = "abcd", t = "bcdf", maxCost = 3
Output: 3
Explanation: "abc" of s can change to "bcd". That costs 3, so the maximum length is 3.
Example 2:
Input: s = "abcd", t = "cdef", maxCost = 3
Output: 1
Explanation: Each character in s costs 2 to change to charactor in t, so the maximum length is 1.
Example 3:
Input: s = "abcd", t = "acde", maxCost = 0
Output: 1
Explanation: You can't make any change, so the maximum length is 1.
Constraints:
1 <= s.length, t.length <= 10^5
0 <= maxCost <= 10^6
s
andt
only contain lower case English letters.
二.解题思路
这道题可以转化为求一个有一堆数的数组的子序列,这个子序列要满足和小于maxCost,并且在所有满足和小于maxCost的子序列中长度最长。
首先考虑能否用动态规划,想了一下不满足无后效性原则,后面出现的数会导致前面的不是最优解
那就老老实实穷举所有可能,滑动窗口。
用两个指针,一个指向开头,一个指向结尾来遍历。
1.尾指针向后移动一个,加上新位置的cost然后判断cost和是否超过maxCost,
2.超过的话头指针向后移动,这个子序列计算结束,计算当前子序列len并更新最大值,并减去移动位置的这几个cost,直到cost和小于maxCost后,
尾指针继续向后移动一个,重复1,2步
算法的复杂度为O(n),因为头指针和尾指针最多分别遍历一次数组。
在我的实现方法里,要注意一下循环结束的是否要再判断一次max_len和当前子序列的长度谁长,
因为可能当前子序列就是最长的那个子序列并且以数组最后一个元素结束,没超过maxCost,就不会进入if语句里面计算len
更新:可以用减法做,会高效一点
更多leetcode算法题解法请关注我的专栏leetcode算法从零到结束或关注我
欢迎大家一起套路一起刷题一起ac
三.源码
class Solution:
def equalSubstring(self, s: str, t: str, maxCost: int) -> int:
len_arr=len(s)
max_len,idx_start,idx_now,cost=0,0,0,0
diff=[abs(ord(s[i])-ord(t[i])) for i in range(len_arr)]
while cost<=maxCost and idx_now<len_arr:
cost+=diff[idx_now]
if cost>maxCost:
len_cur=idx_now-idx_start
max_len=len_cur if len_cur>max_len else max_len
while cost>maxCost:
cost-=diff[idx_start]
idx_start+=1
idx_now+=1
return max(max_len,idx_now-idx_start)
减法做代码由减法源码作者
class Solution:
def equalSubstring(self, s: str, t: str, maxCost: int) -> int:
i = 0
for j in range(len(s)):
maxCost -= abs(ord(s[j]) - ord(t[j]))
if maxCost < 0:
maxCost += abs(ord(s[i]) - ord(t[i]))
i += 1
return j - i + 1