「这是我参与11月更文挑战的第23天,活动详情查看:2021最后一次更文挑战」
说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)
作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题目描述
给你两个长度相同的字符串,s 和 t。
将 s 中的第 i 个字符变到 t 中的第 i 个字符需要 |s[i] - t[i]| 的开销(开销可能为 0),也就是两个字符的 ASCII 码值的差的绝对值。
用于变更字符串的最大预算是 maxCost。在转化字符串时,总开销应当小于等于该预算,这也意味着字符串的转化可能是不完全的。
如果你可以将 s 的子字符串转化为它在 t 中对应的子字符串,则返回可以转化的最大长度。
如果 s 中没有子字符串可以转化成 t 中对应的子字符串,则返回 0。
示例 1:
输入:s = "abcd", t = "bcdf", maxCost = 3 输出:3 解释:s 中的 "abc" 可以变为 "bcd"。开销为 3,所以最大长度为 3。
示例 2:
输入:s = "abcd", t = "cdef", maxCost = 3 输出:1 解释:s 中的任一字符要想变成 t 中对应的字符,其开销都是 2。因此,最大长度为 1。
分析
其实这道题目,理解题意很重要。尤其题目中的和t等长的字符串s,在各个字符变化后,子串的比必须在t中相同位置进行,且子串必须是连续的。比如说,对于s="abcz",t="zabc", maxCost=0的情况(也就是不对s中的字符做改变),返回值是0而不应该是3。对于求满足条件的连续子序列的最大长度的问题,马上想到的就是滑动窗口法。
思路
- 用l和r标记滑动窗口的左右两端,长度(也就是窗口中元素个数)为r-l+1的滑动窗口。
- 设滑动窗口内元素和为ws,以窗口右端位置r为优先移动对象,左端点l跟随右端点r,且保证窗口内部元素和不超过maxCost。
- 每次r遍历结束后,需要及时更新结果遍历ans。
var equalSubstring = function(s, t, maxCost) {
let stemp = s.split("");
let ttemp = t.split("");
let result = 0;
let left = 0,right = 0;
let usedCost = 0;
let tempList = [];
for(let i = 0 ; i< stemp.length; i++) {
tempList.push(Math.abs(stemp[i].charCodeAt() - ttemp[i].charCodeAt()));
}
while(right< stemp.length) {
const val = tempList[right];
if(usedCost + val > maxCost) {// 此时right指针已经增加过,取到的val为下一步的val值
usedCost = usedCost - tempList[left];
left ++;
} else {
usedCost = usedCost + val;
right++;
}
result = Math.max(result, right - left);
}
return result;
};
感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。
写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤