Skip to content

Commit 7dd3a65

Browse files
committed
feat: add solutions to lc problem: No.1208
No.1208.Get Equal Substrings Within Budget
1 parent d026e85 commit 7dd3a65

File tree

6 files changed

+345
-231
lines changed

6 files changed

+345
-231
lines changed

solution/1200-1299/1208.Get Equal Substrings Within Budget/README.md

Lines changed: 163 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,25 @@
5555

5656
<!-- 这里可写通用的实现逻辑 -->
5757

58-
前缀和 + 二分查找。
58+
**方法一:前缀和 + 二分查找**
59+
60+
我们可以创建一个长度为 $n + 1$ 的数组 $f$,其中 $f[i]$ 表示字符串 $s$ 的前 $i$ 个字符与字符串 $t$ 的前 $i$ 个字符的 ASCII 码值的差的绝对值之和。这样,我们就可以通过 $f[j + 1] - f[i]$ 来计算字符串 $s$ 的第 $i$ 个字符到第 $j$ 个字符的 ASCII 码值的差的绝对值之和,其中 $0 \leq i \leq j < n$。
61+
62+
注意到长度具有单调性,即如果存在长度为 $x$ 的子串满足条件,那么长度为 $x - 1$ 的子串也一定满足条件。因此,我们可以使用二分查找的方法来求解最大长度。
63+
64+
我们定义函数 $check(x)$,表示是否存在长度为 $x$ 的子串满足条件。在该函数中,我们只需要枚举所有长度为 $x$ 的子串,判断其是否满足条件即可。如果存在满足条件的子串,那么函数返回 `true`,否则返回 `false`
65+
66+
接下来,我们定义二分查找的左边界 $l$ 为 $0$,右边界 $r$ 为 $n$。在每一步中,我们令 $mid = \lfloor \frac{l + r + 1}{2} \rfloor$,如果函数 $check(mid)$ 的返回值为 `true`,那么我们将左边界更新为 $mid$,否则我们将右边界更新为 $mid - 1$。在二分查找结束后,我们得到的左边界即为答案。
67+
68+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $s$ 的长度。
69+
70+
**方法二:双指针**
71+
72+
我们可以维护两个指针 $j$ 和 $i$,初始时 $i = j = 0$;维护一个变量 $sum$,表示下标区间 $[i,..j]$ 之间的 ASCII 码值的差的绝对值之和。在每一步中,我们将 $i$ 向右移动一位,然后更新 $sum = sum + |s[i] - t[i]|$。如果 $sum \gt maxCost$,那么我们就循环将指针 $j$ 向右移动,并且在移动过程中不断减少 $sum$ 的值,直到 $sum \leq maxCost$。然后我们更新答案,即 $ans = \max(ans, i - j + 1)$。
73+
74+
最后返回答案即可。
75+
76+
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为字符串 $s$ 的长度。
5977

6078
<!-- tabs:start -->
6179

@@ -66,28 +84,39 @@
6684
```python
6785
class Solution:
6886
def equalSubstring(self, s: str, t: str, maxCost: int) -> int:
69-
n = len(s)
70-
presum = [0] * (n + 1)
71-
for i in range(n):
72-
presum[i + 1] = presum[i] + abs(ord(s[i]) - ord(t[i]))
73-
left, right = 0, n
74-
75-
def check(l):
76-
i = 0
77-
while i + l - 1 < n:
78-
j = i + l - 1
79-
if presum[j + 1] - presum[i] <= maxCost:
87+
def check(x):
88+
for i in range(n):
89+
j = i + mid - 1
90+
if j < n and f[j + 1] - f[i] <= maxCost:
8091
return True
81-
i += 1
8292
return False
8393

84-
while left < right:
85-
mid = (left + right + 1) >> 1
94+
n = len(s)
95+
f = list(accumulate((abs(ord(a) - ord(b))
96+
for a, b in zip(s, t)), initial=0))
97+
l, r = 0, n
98+
while l < r:
99+
mid = (l + r + 1) >> 1
86100
if check(mid):
87-
left = mid
101+
l = mid
88102
else:
89-
right = mid - 1
90-
return left
103+
r = mid - 1
104+
return l
105+
```
106+
107+
```python
108+
class Solution:
109+
def equalSubstring(self, s: str, t: str, maxCost: int) -> int:
110+
n = len(s)
111+
sum = j = 0
112+
ans = 0
113+
for i in range(n):
114+
sum += abs(ord(s[i]) - ord(t[i]))
115+
while sum > maxCost:
116+
sum -= abs(ord(s[j]) - ord(t[j]))
117+
j += 1
118+
ans = max(ans, i - j + 1)
119+
return ans
91120
```
92121

93122
### **Java**
@@ -96,66 +125,111 @@ class Solution:
96125

97126
```java
98127
class Solution {
128+
private int maxCost;
129+
private int[] f;
130+
private int n;
131+
99132
public int equalSubstring(String s, String t, int maxCost) {
100-
int n = s.length();
101-
int[] presum = new int[n + 1];
133+
n = s.length();
134+
f = new int[n + 1];
135+
this.maxCost = maxCost;
102136
for (int i = 0; i < n; ++i) {
103-
presum[i + 1] = presum[i] + Math.abs(s.charAt(i) - t.charAt(i));
137+
int x = Math.abs(s.charAt(i) - t.charAt(i));
138+
f[i + 1] = f[i] + x;
104139
}
105-
int left = 0, right = n;
106-
while (left < right) {
107-
int mid = (left + right + 1) >>> 1;
108-
if (check(mid, presum, maxCost, n)) {
109-
left = mid;
140+
int l = 0, r = n;
141+
while (l < r) {
142+
int mid = (l + r + 1) >>> 1;
143+
if (check(mid)) {
144+
l = mid;
110145
} else {
111-
right = mid - 1;
146+
r = mid - 1;
112147
}
113148
}
114-
return left;
149+
return l;
115150
}
116151

117-
private boolean check(int l, int[] s, int maxCost, int n) {
118-
int i = 0;
119-
while (i + l - 1 < n) {
120-
int j = i + l - 1;
121-
if (s[j + 1] - s[i] <= maxCost) {
152+
private boolean check(int x) {
153+
for (int i = 0; i + x - 1 < n; ++i) {
154+
int j = i + x - 1;
155+
if (f[j + 1] - f[i] <= maxCost) {
122156
return true;
123157
}
124-
++i;
125158
}
126159
return false;
127160
}
128161
}
129162
```
130163

164+
```java
165+
class Solution {
166+
public int equalSubstring(String s, String t, int maxCost) {
167+
int n = s.length();
168+
int sum = 0;
169+
int ans = 0;
170+
for (int i = 0, j = 0; i < n; ++i) {
171+
sum += Math.abs(s.charAt(i) - t.charAt(i));
172+
while (sum > maxCost) {
173+
sum -= Math.abs(s.charAt(j) - t.charAt(j));
174+
++j;
175+
}
176+
ans = Math.max(ans, i - j + 1);
177+
}
178+
return ans;
179+
}
180+
}
181+
```
182+
131183
### **C++**
132184

133185
```cpp
134186
class Solution {
135187
public:
136188
int equalSubstring(string s, string t, int maxCost) {
137189
int n = s.size();
138-
vector<int> presum(n + 1);
139-
for (int i = 0; i < n; ++i) presum[i + 1] = presum[i] + abs(s[i] - t[i]);
140-
int left = 0, right = n;
141-
while (left < right) {
142-
int mid = left + right + 1 >> 1;
143-
if (check(mid, presum, maxCost, n))
144-
left = mid;
145-
else
146-
right = mid - 1;
190+
int f[n + 1];
191+
f[0] = 0;
192+
for (int i = 0; i < n; ++i) {
193+
f[i + 1] = f[i] + abs(s[i] - t[i]);
194+
}
195+
auto check = [&](int x) -> bool {
196+
for (int i = 0; i + x - 1 < n; ++i) {
197+
int j = i + x - 1;
198+
if (f[j + 1] - f[i] <= maxCost) {
199+
return true;
200+
}
201+
}
202+
return false;
203+
};
204+
int l = 0, r = n;
205+
while (l < r) {
206+
int mid = (l + r + 1) >> 1;
207+
if (check(mid)) {
208+
l = mid;
209+
} else {
210+
r = mid - 1;
211+
}
147212
}
148-
return left;
213+
return l;
149214
}
215+
};
216+
```
150217
151-
bool check(int l, vector<int>& s, int maxCost, int n) {
152-
int i = 0;
153-
while (i + l - 1 < n) {
154-
int j = i + l - 1;
155-
if (s[j + 1] - s[i] <= maxCost) return true;
156-
++i;
218+
```cpp
219+
class Solution {
220+
public:
221+
int equalSubstring(string s, string t, int maxCost) {
222+
int n = s.size();
223+
int ans = 0, sum = 0;
224+
for (int i = 0, j = 0; i < n; ++i) {
225+
sum += abs(s[i] - t[i]);
226+
while (sum > maxCost) {
227+
sum -= abs(s[j] - t[j]);
228+
++j;
229+
}
230+
ans = max(ans, i - j + 1);
157231
}
158-
return false;
232+
return ans;
159233
}
160234
};
161235
```
@@ -165,39 +239,58 @@ public:
165239
```go
166240
func equalSubstring(s string, t string, maxCost int) int {
167241
n := len(s)
168-
presum := make([]int, n+1)
169-
for i, c := range s {
170-
presum[i+1] = presum[i] + abs(int(c)-int(t[i]))
242+
f := make([]int, n+1)
243+
for i, a := range s {
244+
f[i+1] = f[i] + abs(int(a)-int(t[i]))
171245
}
172-
173-
left, right := 0, n
174-
check := func(l int) bool {
175-
i := 0
176-
for i+l-1 < n {
177-
j := i + l - 1
178-
if presum[j+1]-presum[i] <= maxCost {
246+
check := func(x int) bool {
247+
for i := 0; i+x-1 < n; i++ {
248+
if f[i+x]-f[i] <= maxCost {
179249
return true
180250
}
181-
i++
182251
}
183252
return false
184253
}
185-
for left < right {
186-
mid := (left + right + 1) >> 1
254+
l, r := 0, n
255+
for l < r {
256+
mid := (l + r + 1) >> 1
187257
if check(mid) {
188-
left = mid
258+
l = mid
189259
} else {
190-
right = mid - 1
260+
r = mid - 1
261+
}
262+
}
263+
return l
264+
}
265+
266+
func abs(x int) int {
267+
if x < 0 {
268+
return -x
269+
}
270+
return x
271+
}
272+
```
273+
274+
```go
275+
func equalSubstring(s string, t string, maxCost int) (ans int) {
276+
var sum, j int
277+
for i := range s {
278+
sum += abs(int(s[i]) - int(t[i]))
279+
for ; sum > maxCost; j++ {
280+
sum -= abs(int(s[j]) - int(t[j]))
281+
}
282+
if ans < i-j+1 {
283+
ans = i - j + 1
191284
}
192285
}
193-
return left
286+
return
194287
}
195288

196289
func abs(x int) int {
197-
if x > 0 {
198-
return x
290+
if x < 0 {
291+
return -x
199292
}
200-
return -x
293+
return x
201294
}
202295
```
203296

0 commit comments

Comments
 (0)