Skip to content

Commit 5671f72

Browse files
authored
feat: add solutions to lc/lcof2 problems (#1430)
* lc No.0446.Arithmetic Slices II - Subsequence * lc No.0466.Count The Repetitions * lcof2 No.092.将字符串翻转到单调递增
1 parent 15a1536 commit 5671f72

File tree

20 files changed

+816
-114
lines changed

20 files changed

+816
-114
lines changed

lcof2/剑指 Offer II 092. 翻转字符/README.md

+70-45
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,13 @@
5353

5454
<!-- 这里可写通用的实现逻辑 -->
5555

56-
我们需要找到一个分界点 `i`,使 `[:i]` 全为 0,`[i:]` 全为 1,并且翻转次数最少,问题就转换成计算 `i` 的左右两侧的翻转次数,可以用前缀和进行优化
56+
**方法一:枚举**
57+
58+
我们先预处理得到右侧的 $0$ 的个数,记为 $right0$,初始化一个变量 $left0$,表示左侧的 $0$ 的个数。如果最终字符串变成全 `'0'` 或者全 `'1'`,那么答案为 $ans= \min(right0, n - right0)$。
59+
60+
接下来,我们枚举每个位置作为 `'0'``'1'` 的分界点(约定分界点为 `'0'`),计算出以当前位置为分界点的答案,最后取最小值即可。
61+
62+
时间复杂度 $O(n)$,其中 $n$ 是字符串的长度。空间复杂度 $O(1)$。
5763

5864
<!-- tabs:start -->
5965

@@ -64,15 +70,14 @@
6470
```python
6571
class Solution:
6672
def minFlipsMonoIncr(self, s: str) -> int:
73+
left0, right0 = 0, s.count("0")
6774
n = len(s)
68-
left, right = [0] * (n + 1), [0] * (n + 1)
69-
ans = 0x3F3F3F3F
70-
for i in range(1, n + 1):
71-
left[i] = left[i - 1] + (1 if s[i - 1] == '1' else 0)
72-
for i in range(n - 1, -1, -1):
73-
right[i] = right[i + 1] + (1 if s[i] == '0' else 0)
74-
for i in range(0, n + 1):
75-
ans = min(ans, left[i] + right[i])
75+
ans = min(right0, n - right0)
76+
for i, c in enumerate(s, 1):
77+
x = int(c)
78+
right0 -= x ^ 1
79+
left0 += x ^ 1
80+
ans = min(ans, i - left0 + right0)
7681
return ans
7782
```
7883

@@ -84,17 +89,18 @@ class Solution:
8489
class Solution {
8590
public int minFlipsMonoIncr(String s) {
8691
int n = s.length();
87-
int[] left = new int[n + 1];
88-
int[] right = new int[n + 1];
89-
int ans = Integer.MAX_VALUE;
90-
for (int i = 1; i <= n; i++) {
91-
left[i] = left[i - 1] + (s.charAt(i - 1) == '1' ? 1 : 0);
92-
}
93-
for (int i = n - 1; i >= 0; i--) {
94-
right[i] = right[i + 1] + (s.charAt(i) == '0' ? 1 : 0);
92+
int left0 = 0, right0 = 0;
93+
for (int i = 0; i < n; ++i) {
94+
if (s.charAt(i) == '0') {
95+
++right0;
96+
}
9597
}
96-
for (int i = 0; i <= n; i++) {
97-
ans = Math.min(ans, left[i] + right[i]);
98+
int ans = Math.min(right0, n - right0);
99+
for (int i = 1; i <= n; ++i) {
100+
int x = s.charAt(i - 1) == '0' ? 0 : 1;
101+
right0 -= x ^ 1;
102+
left0 += x ^ 1;
103+
ans = Math.min(ans, i - left0 + right0);
98104
}
99105
return ans;
100106
}
@@ -108,16 +114,16 @@ class Solution {
108114
public:
109115
int minFlipsMonoIncr(string s) {
110116
int n = s.size();
111-
vector<int> left(n + 1, 0), right(n + 1, 0);
112-
int ans = INT_MAX;
113-
for (int i = 1; i <= n; ++i) {
114-
left[i] = left[i - 1] + (s[i - 1] == '1');
117+
int left0 = 0, right0 = 0;
118+
for (char& c : s) {
119+
right0 += c == '0';
115120
}
116-
for (int i = n - 1; i >= 0; --i) {
117-
right[i] = right[i + 1] + (s[i] == '0');
118-
}
119-
for (int i = 0; i <= n; i++) {
120-
ans = min(ans, left[i] + right[i]);
121+
int ans = min(right0, n - right0);
122+
for (int i = 1; i <= n; ++i) {
123+
int x = s[i - 1] == '1';
124+
right0 -= x ^ 1;
125+
left0 += x ^ 1;
126+
ans = min(ans, i - left0 + right0);
121127
}
122128
return ans;
123129
}
@@ -129,31 +135,50 @@ public:
129135
```go
130136
func minFlipsMonoIncr(s string) int {
131137
n := len(s)
132-
left, right := make([]int, n+1), make([]int, n+1)
133-
ans := math.MaxInt32
134-
for i := 1; i <= n; i++ {
135-
left[i] = left[i-1]
136-
if s[i-1] == '1' {
137-
left[i]++
138+
left0, right0 := 0, 0
139+
for _, c := range s {
140+
if c == '0' {
141+
right0++
138142
}
139143
}
140-
for i := n - 1; i >= 0; i-- {
141-
right[i] = right[i+1]
142-
if s[i] == '0' {
143-
right[i]++
144+
ans := min(right0, n-right0)
145+
for i, c := range s {
146+
x := 0
147+
if c == '1' {
148+
x = 1
144149
}
145-
}
146-
for i := 0; i <= n; i++ {
147-
ans = min(ans, left[i]+right[i])
150+
right0 -= x ^ 1
151+
left0 += x ^ 1
152+
ans = min(ans, i+1-left0+right0)
148153
}
149154
return ans
150155
}
151156
152-
func min(x, y int) int {
153-
if x < y {
154-
return x
157+
func min(a, b int) int {
158+
if a < b {
159+
return a
155160
}
156-
return y
161+
return b
162+
}
163+
```
164+
165+
### **TypeScript**
166+
167+
```ts
168+
function minFlipsMonoIncr(s: string): number {
169+
const n = s.length;
170+
let [left0, right0] = [0, 0];
171+
for (const c of s) {
172+
right0 += c === '0' ? 1 : 0;
173+
}
174+
let ans = Math.min(right0, n - right0);
175+
for (let i = 1; i <= n; ++i) {
176+
const x = s[i - 1] === '0' ? 0 : 1;
177+
right0 -= x ^ 1;
178+
left0 += x ^ 1;
179+
ans = Math.min(ans, i - left0 + right0);
180+
}
181+
return ans;
157182
}
158183
```
159184

Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
class Solution {
2-
public:
3-
int minFlipsMonoIncr(string s) {
4-
int n = s.size();
5-
vector<int> left(n + 1, 0), right(n + 1, 0);
6-
int ans = INT_MAX;
7-
for (int i = 1; i <= n; ++i) {
8-
left[i] = left[i - 1] + (s[i - 1] == '1');
9-
}
10-
for (int i = n - 1; i >= 0; --i) {
11-
right[i] = right[i + 1] + (s[i] == '0');
12-
}
13-
for (int i = 0; i <= n; i++) {
14-
ans = min(ans, left[i] + right[i]);
15-
}
16-
return ans;
17-
}
18-
};
1+
class Solution {
2+
public:
3+
int minFlipsMonoIncr(string s) {
4+
int n = s.size();
5+
int left0 = 0, right0 = 0;
6+
for (char& c : s) {
7+
right0 += c == '0';
8+
}
9+
int ans = min(right0, n - right0);
10+
for (int i = 1; i <= n; ++i) {
11+
int x = s[i - 1] == '1';
12+
right0 -= x ^ 1;
13+
left0 += x ^ 1;
14+
ans = min(ans, i - left0 + right0);
15+
}
16+
return ans;
17+
}
18+
};
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
func minFlipsMonoIncr(s string) int {
22
n := len(s)
3-
left, right := make([]int, n+1), make([]int, n+1)
4-
ans := math.MaxInt32
5-
for i := 1; i <= n; i++ {
6-
left[i] = left[i-1]
7-
if s[i-1] == '1' {
8-
left[i]++
3+
left0, right0 := 0, 0
4+
for _, c := range s {
5+
if c == '0' {
6+
right0++
97
}
108
}
11-
for i := n - 1; i >= 0; i-- {
12-
right[i] = right[i+1]
13-
if s[i] == '0' {
14-
right[i]++
9+
ans := min(right0, n-right0)
10+
for i, c := range s {
11+
x := 0
12+
if c == '1' {
13+
x = 1
1514
}
16-
}
17-
for i := 0; i <= n; i++ {
18-
ans = min(ans, left[i]+right[i])
15+
right0 -= x ^ 1
16+
left0 += x ^ 1
17+
ans = min(ans, i+1-left0+right0)
1918
}
2019
return ans
2120
}
2221

23-
func min(x, y int) int {
24-
if x < y {
25-
return x
22+
func min(a, b int) int {
23+
if a < b {
24+
return a
2625
}
27-
return y
26+
return b
2827
}
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1-
class Solution {
2-
public int minFlipsMonoIncr(String s) {
3-
int n = s.length();
4-
int[] left = new int[n + 1];
5-
int[] right = new int[n + 1];
6-
int ans = Integer.MAX_VALUE;
7-
for (int i = 1; i <= n; i++) {
8-
left[i] = left[i - 1] + (s.charAt(i - 1) == '1' ? 1 : 0);
9-
}
10-
for (int i = n - 1; i >= 0; i--) {
11-
right[i] = right[i + 1] + (s.charAt(i) == '0' ? 1 : 0);
12-
}
13-
for (int i = 0; i <= n; i++) {
14-
ans = Math.min(ans, left[i] + right[i]);
15-
}
16-
return ans;
17-
}
18-
}
1+
class Solution {
2+
public int minFlipsMonoIncr(String s) {
3+
int n = s.length();
4+
int left0 = 0, right0 = 0;
5+
for (int i = 0; i < n; ++i) {
6+
if (s.charAt(i) == '0') {
7+
++right0;
8+
}
9+
}
10+
int ans = Math.min(right0, n - right0);
11+
for (int i = 1; i <= n; ++i) {
12+
int x = s.charAt(i - 1) == '0' ? 0 : 1;
13+
right0 -= x ^ 1;
14+
left0 += x ^ 1;
15+
ans = Math.min(ans, i - left0 + right0);
16+
}
17+
return ans;
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
class Solution:
2-
def minFlipsMonoIncr(self, s: str) -> int:
3-
n = len(s)
4-
left, right = [0] * (n + 1), [0] * (n + 1)
5-
ans = 0x3F3F3F3F
6-
for i in range(1, n + 1):
7-
left[i] = left[i - 1] + (1 if s[i - 1] == '1' else 0)
8-
for i in range(n - 1, -1, -1):
9-
right[i] = right[i + 1] + (1 if s[i] == '0' else 0)
10-
for i in range(0, n + 1):
11-
ans = min(ans, left[i] + right[i])
12-
return ans
1+
class Solution:
2+
def minFlipsMonoIncr(self, s: str) -> int:
3+
left0, right0 = 0, s.count("0")
4+
n = len(s)
5+
ans = min(right0, n - right0)
6+
for i, c in enumerate(s, 1):
7+
x = int(c)
8+
right0 -= x ^ 1
9+
left0 += x ^ 1
10+
ans = min(ans, i - left0 + right0)
11+
return ans
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function minFlipsMonoIncr(s: string): number {
2+
const n = s.length;
3+
let [left0, right0] = [0, 0];
4+
for (const c of s) {
5+
right0 += c === '0' ? 1 : 0;
6+
}
7+
let ans = Math.min(right0, n - right0);
8+
for (let i = 1; i <= n; ++i) {
9+
const x = s[i - 1] === '0' ? 0 : 1;
10+
right0 -= x ^ 1;
11+
left0 += x ^ 1;
12+
ans = Math.min(ans, i - left0 + right0);
13+
}
14+
return ans;
15+
}

0 commit comments

Comments
 (0)