Welcome to Subscribe On Youtube
Formatted question description: https://leetcode.ca/all/1208.html
1208. Get Equal Substrings Within Budget
Level
Medium
Description
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.
Solution
Create an array differences
which has length the same as the length of s
and t
, where differences[i]
is the absolute difference between s.charAt(i)
and t.charAt(i)
. Then the problem is converted to another form. Find the length of the longest subarray from differences
such that the sum of all the elements in the subarray is less than or equal to maxCost
.
Use two pointers start
and end
, which point to 0 initially. If differences[0] <= maxCost
, then the length of the longest subarray is at least 1. Each time append a new element to the subarray by moving end
forward. If the subarray’s sum is greater than maxCost
, then remove start
forward to reduce the subarray’s length until the subarray’s sum is less than or equal to maxCost
. After this, update the length of the longest subarray. After the whole array is looped over, return the length of the longest subarray.
-
class Solution { public int equalSubstring(String s, String t, int maxCost) { int length = s.length(); int[] differences = new int[length]; for (int i = 0; i < length; i++) { char c1 = s.charAt(i), c2 = t.charAt(i); differences[i] = Math.abs(c1 - c2); } int maxLength = 0; int start = 0, end = 0; int sum = differences[0]; if (sum <= maxCost) maxLength = 1; while (end < length - 1) { sum += differences[++end]; while (sum > maxCost) sum -= differences[start++]; maxLength = Math.max(maxLength, end - start + 1); } return maxLength; } }
-
// OJ: https://leetcode.com/problems/get-equal-substrings-within-budget/ // Time: O(N) // Space: O(1) class Solution { public: int equalSubstring(string s, string t, int maxCost) { int i = 0, j = 0, N = s.size(), cost = 0, ans = 0; for (; j < N; ++j) { cost += abs(s[j] - t[j]); for (; cost > maxCost; ++i) cost -= abs(s[i] - t[i]); ans = max(ans, j - i + 1); } return ans; } };
-
class Solution: def equalSubstring(self, s: str, t: str, maxCost: int) -> int: n = len(s) presum = [0] * (n + 1) for i in range(n): presum[i + 1] = presum[i] + abs(ord(s[i]) - ord(t[i])) left, right = 0, n def check(l): i = 0 while i + l - 1 < n: j = i + l - 1 if presum[j + 1] - presum[i] <= maxCost: return True i += 1 return False while left < right: mid = (left + right + 1) >> 1 if check(mid): left = mid else: right = mid - 1 return left ############ def findSubArray(nums): N = len(nums) # 数组/字符串长度 left, right = 0, 0 # 双指针,表示当前遍历的区间[left, right],闭区间 sums = 0 # 用于统计 子数组/子区间 是否有效,根据题目可能会改成求和/计数 res = 0 # 保存最大的满足题目要求的 子数组/子串 长度 while right < N: # 当右边的指针没有搜索到 数组/字符串 的结尾 sums += nums[right] # 增加当前右边指针的数字/字符的求和/计数 while 区间[left, right]不符合题意:# 此时需要一直移动左指针,直至找到一个符合题意的区间 sums -= nums[left] # 移动左指针前需要从counter中减少left位置字符的求和/计数 left += 1 # 真正的移动左指针,注意不能跟上面一行代码写反 # 到 while 结束时,我们找到了一个符合题意要求的 子数组/子串 res = max(res, right - left + 1) # 需要更新结果 right += 1 # 移动右指针,去探索新的区间 return res
-
func equalSubstring(s string, t string, maxCost int) (ans int) { var sum, j int for i := range s { sum += abs(int(s[i]) - int(t[i])) for ; sum > maxCost; j++ { sum -= abs(int(s[j]) - int(t[j])) } if ans < i-j+1 { ans = i - j + 1 } } return } func abs(x int) int { if x < 0 { return -x } return x }