Skip to content

Commit

Permalink
feat: add solutions to lc/lcof2 problems
Browse files Browse the repository at this point in the history
lcof2 No.092 & lc No.0926.Flip String to Monotone Increasing
  • Loading branch information
maolonglong committed Jan 1, 2022
1 parent 79be796 commit f6803e3
Show file tree
Hide file tree
Showing 11 changed files with 411 additions and 3 deletions.
88 changes: 87 additions & 1 deletion lcof2/剑指 Offer II 092. 翻转字符/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,108 @@

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

我们需要找到一个分界点 `i`,使 `[:i]` 全为 0,`[i:]` 全为 1,并且翻转次数最少,问题就转换成计算 `i` 的左右两侧的翻转次数,可以用前缀和进行优化

<!-- tabs:start -->

### **Python3**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```python

class Solution:
def minFlipsMonoIncr(self, s: str) -> int:
n = len(s)
left, right = [0] * (n + 1), [0] * (n + 1)
ans = 0x3f3f3f3f
for i in range(1, n + 1):
left[i] = left[i - 1] + (1 if s[i - 1] == '1' else 0)
for i in range(n - 1, -1, -1):
right[i] = right[i + 1] + (1 if s[i] == '0' else 0)
for i in range(0, n + 1):
ans = min(ans, left[i] + right[i])
return ans
```

### **Java**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```java
class Solution {
public int minFlipsMonoIncr(String s) {
int n = s.length();
int[] left = new int[n + 1];
int[] right = new int[n + 1];
int ans = Integer.MAX_VALUE;
for (int i = 1; i <= n; i++) {
left[i] = left[i - 1] + (s.charAt(i - 1) == '1' ? 1 : 0);
}
for (int i = n - 1; i >= 0; i--) {
right[i] = right[i + 1] + (s.charAt(i) == '0' ? 1 : 0);
}
for (int i = 0; i <= n; i++) {
ans = Math.min(ans, left[i] + right[i]);
}
return ans;
}
}
```

### **C++**

```cpp
class Solution {
public:
int minFlipsMonoIncr(string s) {
int n = s.size();
vector<int> left(n + 1, 0), right(n + 1, 0);
int ans = INT_MAX;
for (int i = 1; i <= n; ++i) {
left[i] = left[i - 1] + (s[i - 1] == '1');
}
for (int i = n - 1; i >= 0; --i) {
right[i] = right[i + 1] + (s[i] == '0');
}
for (int i = 0; i <= n; i++) {
ans = min(ans, left[i] + right[i]);
}
return ans;
}
};
```
### **Go**
```go
func minFlipsMonoIncr(s string) int {
n := len(s)
left, right := make([]int, n+1), make([]int, n+1)
ans := math.MaxInt32
for i := 1; i <= n; i++ {
left[i] = left[i-1]
if s[i-1] == '1' {
left[i]++
}
}
for i := n - 1; i >= 0; i-- {
right[i] = right[i+1]
if s[i] == '0' {
right[i]++
}
}
for i := 0; i <= n; i++ {
ans = min(ans, left[i]+right[i])
}
return ans
}
func min(x, y int) int {
if x < y {
return x
}
return y
}
```

### **...**
Expand Down
18 changes: 18 additions & 0 deletions lcof2/剑指 Offer II 092. 翻转字符/Solution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class Solution {
public:
int minFlipsMonoIncr(string s) {
int n = s.size();
vector<int> left(n + 1, 0), right(n + 1, 0);
int ans = INT_MAX;
for (int i = 1; i <= n; ++i) {
left[i] = left[i - 1] + (s[i - 1] == '1');
}
for (int i = n - 1; i >= 0; --i) {
right[i] = right[i + 1] + (s[i] == '0');
}
for (int i = 0; i <= n; i++) {
ans = min(ans, left[i] + right[i]);
}
return ans;
}
};
28 changes: 28 additions & 0 deletions lcof2/剑指 Offer II 092. 翻转字符/Solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
func minFlipsMonoIncr(s string) int {
n := len(s)
left, right := make([]int, n+1), make([]int, n+1)
ans := math.MaxInt32
for i := 1; i <= n; i++ {
left[i] = left[i-1]
if s[i-1] == '1' {
left[i]++
}
}
for i := n - 1; i >= 0; i-- {
right[i] = right[i+1]
if s[i] == '0' {
right[i]++
}
}
for i := 0; i <= n; i++ {
ans = min(ans, left[i]+right[i])
}
return ans
}

func min(x, y int) int {
if x < y {
return x
}
return y
}
18 changes: 18 additions & 0 deletions lcof2/剑指 Offer II 092. 翻转字符/Solution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class Solution {
public int minFlipsMonoIncr(String s) {
int n = s.length();
int[] left = new int[n + 1];
int[] right = new int[n + 1];
int ans = Integer.MAX_VALUE;
for (int i = 1; i <= n; i++) {
left[i] = left[i - 1] + (s.charAt(i - 1) == '1' ? 1 : 0);
}
for (int i = n - 1; i >= 0; i--) {
right[i] = right[i + 1] + (s.charAt(i) == '0' ? 1 : 0);
}
for (int i = 0; i <= n; i++) {
ans = Math.min(ans, left[i] + right[i]);
}
return ans;
}
}
12 changes: 12 additions & 0 deletions lcof2/剑指 Offer II 092. 翻转字符/Solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class Solution:
def minFlipsMonoIncr(self, s: str) -> int:
n = len(s)
left, right = [0] * (n + 1), [0] * (n + 1)
ans = 0x3f3f3f3f
for i in range(1, n + 1):
left[i] = left[i - 1] + (1 if s[i - 1] == '1' else 0)
for i in range(n - 1, -1, -1):
right[i] = right[i + 1] + (1 if s[i] == '0' else 0)
for i in range(0, n + 1):
ans = min(ans, left[i] + right[i])
return ans
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,108 @@

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

我们需要找到一个分界点 `i`,使 `[:i]` 全为 0,`[i:]` 全为 1,并且翻转次数最少,问题就转换成计算 `i` 的左右两侧的翻转次数,可以用前缀和进行优化

<!-- tabs:start -->

### **Python3**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```python

class Solution:
def minFlipsMonoIncr(self, s: str) -> int:
n = len(s)
left, right = [0] * (n + 1), [0] * (n + 1)
ans = 0x3f3f3f3f
for i in range(1, n + 1):
left[i] = left[i - 1] + (1 if s[i - 1] == '1' else 0)
for i in range(n - 1, -1, -1):
right[i] = right[i + 1] + (1 if s[i] == '0' else 0)
for i in range(0, n + 1):
ans = min(ans, left[i] + right[i])
return ans
```

### **Java**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```java
class Solution {
public int minFlipsMonoIncr(String s) {
int n = s.length();
int[] left = new int[n + 1];
int[] right = new int[n + 1];
int ans = Integer.MAX_VALUE;
for (int i = 1; i <= n; i++) {
left[i] = left[i - 1] + (s.charAt(i - 1) == '1' ? 1 : 0);
}
for (int i = n - 1; i >= 0; i--) {
right[i] = right[i + 1] + (s.charAt(i) == '0' ? 1 : 0);
}
for (int i = 0; i <= n; i++) {
ans = Math.min(ans, left[i] + right[i]);
}
return ans;
}
}
```

### **C++**

```cpp
class Solution {
public:
int minFlipsMonoIncr(string s) {
int n = s.size();
vector<int> left(n + 1, 0), right(n + 1, 0);
int ans = INT_MAX;
for (int i = 1; i <= n; ++i) {
left[i] = left[i - 1] + (s[i - 1] == '1');
}
for (int i = n - 1; i >= 0; --i) {
right[i] = right[i + 1] + (s[i] == '0');
}
for (int i = 0; i <= n; i++) {
ans = min(ans, left[i] + right[i]);
}
return ans;
}
};
```
### **Go**
```go
func minFlipsMonoIncr(s string) int {
n := len(s)
left, right := make([]int, n+1), make([]int, n+1)
ans := math.MaxInt32
for i := 1; i <= n; i++ {
left[i] = left[i-1]
if s[i-1] == '1' {
left[i]++
}
}
for i := n - 1; i >= 0; i-- {
right[i] = right[i+1]
if s[i] == '0' {
right[i]++
}
}
for i := 0; i <= n; i++ {
ans = min(ans, left[i]+right[i])
}
return ans
}
func min(x, y int) int {
if x < y {
return x
}
return y
}
```

### **...**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,97 @@
### **Python3**

```python

class Solution:
def minFlipsMonoIncr(self, s: str) -> int:
n = len(s)
left, right = [0] * (n + 1), [0] * (n + 1)
ans = 0x3f3f3f3f
for i in range(1, n + 1):
left[i] = left[i - 1] + (1 if s[i - 1] == '1' else 0)
for i in range(n - 1, -1, -1):
right[i] = right[i + 1] + (1 if s[i] == '0' else 0)
for i in range(0, n + 1):
ans = min(ans, left[i] + right[i])
return ans
```

### **Java**

```java
class Solution {
public int minFlipsMonoIncr(String s) {
int n = s.length();
int[] left = new int[n + 1];
int[] right = new int[n + 1];
int ans = Integer.MAX_VALUE;
for (int i = 1; i <= n; i++) {
left[i] = left[i - 1] + (s.charAt(i - 1) == '1' ? 1 : 0);
}
for (int i = n - 1; i >= 0; i--) {
right[i] = right[i + 1] + (s.charAt(i) == '0' ? 1 : 0);
}
for (int i = 0; i <= n; i++) {
ans = Math.min(ans, left[i] + right[i]);
}
return ans;
}
}
```

### **C++**

```cpp
class Solution {
public:
int minFlipsMonoIncr(string s) {
int n = s.size();
vector<int> left(n + 1, 0), right(n + 1, 0);
int ans = INT_MAX;
for (int i = 1; i <= n; ++i) {
left[i] = left[i - 1] + (s[i - 1] == '1');
}
for (int i = n - 1; i >= 0; --i) {
right[i] = right[i + 1] + (s[i] == '0');
}
for (int i = 0; i <= n; i++) {
ans = min(ans, left[i] + right[i]);
}
return ans;
}
};
```
### **Go**
```go
func minFlipsMonoIncr(s string) int {
n := len(s)
left, right := make([]int, n+1), make([]int, n+1)
ans := math.MaxInt32
for i := 1; i <= n; i++ {
left[i] = left[i-1]
if s[i-1] == '1' {
left[i]++
}
}
for i := n - 1; i >= 0; i-- {
right[i] = right[i+1]
if s[i] == '0' {
right[i]++
}
}
for i := 0; i <= n; i++ {
ans = min(ans, left[i]+right[i])
}
return ans
}
func min(x, y int) int {
if x < y {
return x
}
return y
}
```

### **...**
Expand Down
Loading

0 comments on commit f6803e3

Please sign in to comment.