Skip to content

feat: add solutions to lc problem: No.2116 #4132

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,17 @@ tags:

### 方法一:贪心 + 两次遍历

我们观察发现,奇数长度的字符串一定不是有效的括号字符串,因为无论怎么匹配,都会剩下一个括号。因此,如果字符串 $s$ 的长度是奇数,提前返回 `false`
我们观察发现,奇数长度的字符串一定不是有效的括号字符串,因为无论怎么匹配,都会剩下一个括号。因此,如果字符串 $s$ 的长度是奇数,提前返回 $\textit{false}$

接下来,我们进行两次遍历。

第一次从左到右,判断所有的 `'('` 括号是否可以被 `')'` 或者可变括号匹配,如果不可以,直接返回 `false`
第一次从左到右,判断所有的 `'('` 括号是否可以被 `')'` 或者可变括号匹配,如果不可以,直接返回 $\textit{false}$

第二次从右到左,判断所有的 `')'` 括号是否可以被 `'('` 或者可变括号匹配,如果不可以,直接返回 `false`
第二次从右到左,判断所有的 `')'` 括号是否可以被 `'('` 或者可变括号匹配,如果不可以,直接返回 $\textit{false}$

遍历结束,说明所有的括号都可以被匹配,字符串 $s$ 是有效的括号字符串,返回 `true`
遍历结束,说明所有的括号都可以被匹配,字符串 $s$ 是有效的括号字符串,返回 $\textit{true}$

时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为字符串 $s$ 的长度。
时间复杂度 $O(n)$,其中 $n$ 为字符串 $s$ 的长度。空间复杂度 $O(1)$

相似题目:

Expand Down Expand Up @@ -240,6 +240,38 @@ func canBeValid(s string, locked string) bool {
}
```

#### TypeScript

```ts
function canBeValid(s: string, locked: string): boolean {
const n = s.length;
if (n & 1) {
return false;
}
let x = 0;
for (let i = 0; i < n; ++i) {
if (s[i] === '(' || locked[i] === '0') {
++x;
} else if (x > 0) {
--x;
} else {
return false;
}
}
x = 0;
for (let i = n - 1; i >= 0; --i) {
if (s[i] === ')' || locked[i] === '0') {
++x;
} else if (x > 0) {
--x;
} else {
return false;
}
}
return true;
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ We change s[0] and s[4] to &#39;(&#39; while leaving s[2] and s[5] unchanged to
<pre>
<strong>Input:</strong> s = &quot;)&quot;, locked = &quot;0&quot;
<strong>Output:</strong> false
<strong>Explanation:</strong> locked permits us to change s[0].
<strong>Explanation:</strong> locked permits us to change s[0].
Changing s[0] to either &#39;(&#39; or &#39;)&#39; will not make s valid.
</pre>

Expand All @@ -68,7 +68,7 @@ Changing s[0] to either &#39;(&#39; or &#39;)&#39; will not make s valid.
<pre>
<strong>Input:</strong> s = &quot;(((())(((())&quot;, locked = &quot;111111010111&quot;
<strong>Output:</strong> false
<strong>Explanation:</strong> locked permits us to change s[6] and s[8].
<strong>Explanation:</strong> locked permits us to change s[6] and s[8].
We change s[6] and s[8] to &#39;)&#39; to make s valid.
</pre>

Expand All @@ -88,7 +88,23 @@ We change s[6] and s[8] to &#39;)&#39; to make s valid.

<!-- solution:start -->

### Solution 1
### Solution 1: Greedy + Two Passes

We observe that a string of odd length cannot be a valid parentheses string because there will always be one unmatched parenthesis. Therefore, if the length of the string $s$ is odd, return $\textit{false}$ immediately.

Next, we perform two passes.

The first pass goes from left to right, checking if all `'('` parentheses can be matched by `')'` or changeable parentheses. If not, return $\textit{false}$.

The second pass goes from right to left, checking if all `')'` parentheses can be matched by `'('` or changeable parentheses. If not, return $\textit{false}$.

If both passes complete successfully, it means all parentheses can be matched, and the string $s$ is a valid parentheses string. Return $\textit{true}$.

The time complexity is $O(n)$, where $n$ is the length of the string $s$. The space complexity is $O(1)$.

Similar problems:

- [678. Valid Parenthesis String](https://github.com/doocs/leetcode/blob/main/solution/0600-0699/0678.Valid%20Parenthesis%20String/README_EN.md)

<!-- tabs:start -->

Expand Down Expand Up @@ -220,6 +236,38 @@ func canBeValid(s string, locked string) bool {
}
```

#### TypeScript

```ts
function canBeValid(s: string, locked: string): boolean {
const n = s.length;
if (n & 1) {
return false;
}
let x = 0;
for (let i = 0; i < n; ++i) {
if (s[i] === '(' || locked[i] === '0') {
++x;
} else if (x > 0) {
--x;
} else {
return false;
}
}
x = 0;
for (let i = n - 1; i >= 0; --i) {
if (s[i] === ')' || locked[i] === '0') {
++x;
} else if (x > 0) {
--x;
} else {
return false;
}
}
return true;
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
function canBeValid(s: string, locked: string): boolean {
const n = s.length;
if (n & 1) {
return false;
}
let x = 0;
for (let i = 0; i < n; ++i) {
if (s[i] === '(' || locked[i] === '0') {
++x;
} else if (x > 0) {
--x;
} else {
return false;
}
}
x = 0;
for (let i = n - 1; i >= 0; --i) {
if (s[i] === ')' || locked[i] === '0') {
++x;
} else if (x > 0) {
--x;
} else {
return false;
}
}
return true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ tags:
<strong>输入:</strong>left = 2, right = 11
<strong>输出:</strong>"399168e2"
<strong>解释:</strong>乘积为 39916800 。
有 2 个后缀 0 ,删除后得到 399168 。缩写的结尾为 "e2" 。
删除后缀 0 后是 6 位数,不需要进一步缩写。
有 2 个后缀 0 ,删除后得到 399168 。缩写的结尾为 "e2" 。
删除后缀 0 后是 6 位数,不需要进一步缩写。
所以,最终将乘积表示为 "399168e2" 。
</pre>

Expand Down Expand Up @@ -98,39 +98,36 @@ tags:
#### Python3

```python
import numpy


class Solution:
def abbreviateProduct(self, left: int, right: int) -> str:
cnt2 = cnt5 = 0
z = numpy.float128(0)
for x in range(left, right + 1):
z += numpy.log10(x)
while x % 2 == 0:
x //= 2
cnt2 += 1
x //= 2
while x % 5 == 0:
x //= 5
cnt5 += 1
x //= 5
c = cnt2 = cnt5 = min(cnt2, cnt5)
suf = y = 1
pre = suf = 1
gt = False
for x in range(left, right + 1):
while cnt2 and x % 2 == 0:
x //= 2
suf *= x
while cnt2 and suf % 2 == 0:
suf //= 2
cnt2 -= 1
while cnt5 and x % 5 == 0:
x //= 5
while cnt5 and suf % 5 == 0:
suf //= 5
cnt5 -= 1
suf = suf * x % 100000
if not gt:
y *= x
gt = y >= 1e10
if not gt:
return str(y) + "e" + str(c)
pre = int(pow(10, z - int(z) + 4))
return str(pre) + "..." + str(suf).zfill(5) + "e" + str(c)
if suf >= 1e10:
gt = True
suf %= int(1e10)
pre *= x
while pre > 1e5:
pre /= 10
if gt:
return str(int(pre)) + "..." + str(suf % int(1e5)).zfill(5) + "e" + str(c)
return str(suf) + "e" + str(c)
```

#### Java
Expand Down Expand Up @@ -271,49 +268,4 @@ func abbreviateProduct(left int, right int) string {

<!-- solution:end -->

<!-- solution:start -->

### 方法二

<!-- tabs:start -->

#### Python3

```python
class Solution:
def abbreviateProduct(self, left: int, right: int) -> str:
cnt2 = cnt5 = 0
for x in range(left, right + 1):
while x % 2 == 0:
cnt2 += 1
x //= 2
while x % 5 == 0:
cnt5 += 1
x //= 5
c = cnt2 = cnt5 = min(cnt2, cnt5)
pre = suf = 1
gt = False
for x in range(left, right + 1):
suf *= x
while cnt2 and suf % 2 == 0:
suf //= 2
cnt2 -= 1
while cnt5 and suf % 5 == 0:
suf //= 5
cnt5 -= 1
if suf >= 1e10:
gt = True
suf %= int(1e10)
pre *= x
while pre > 1e5:
pre /= 10
if gt:
return str(int(pre)) + "..." + str(suf % int(1e5)).zfill(5) + 'e' + str(c)
return str(suf) + "e" + str(c)
```

<!-- tabs:end -->

<!-- solution:end -->

<!-- problem:end -->
Original file line number Diff line number Diff line change
Expand Up @@ -95,39 +95,36 @@ Hence, the abbreviated product is &quot;399168e2&quot;.
#### Python3

```python
import numpy


class Solution:
def abbreviateProduct(self, left: int, right: int) -> str:
cnt2 = cnt5 = 0
z = numpy.float128(0)
for x in range(left, right + 1):
z += numpy.log10(x)
while x % 2 == 0:
x //= 2
cnt2 += 1
x //= 2
while x % 5 == 0:
x //= 5
cnt5 += 1
x //= 5
c = cnt2 = cnt5 = min(cnt2, cnt5)
suf = y = 1
pre = suf = 1
gt = False
for x in range(left, right + 1):
while cnt2 and x % 2 == 0:
x //= 2
suf *= x
while cnt2 and suf % 2 == 0:
suf //= 2
cnt2 -= 1
while cnt5 and x % 5 == 0:
x //= 5
while cnt5 and suf % 5 == 0:
suf //= 5
cnt5 -= 1
suf = suf * x % 100000
if not gt:
y *= x
gt = y >= 1e10
if not gt:
return str(y) + "e" + str(c)
pre = int(pow(10, z - int(z) + 4))
return str(pre) + "..." + str(suf).zfill(5) + "e" + str(c)
if suf >= 1e10:
gt = True
suf %= int(1e10)
pre *= x
while pre > 1e5:
pre /= 10
if gt:
return str(int(pre)) + "..." + str(suf % int(1e5)).zfill(5) + "e" + str(c)
return str(suf) + "e" + str(c)
```

#### Java
Expand Down Expand Up @@ -268,49 +265,4 @@ func abbreviateProduct(left int, right int) string {

<!-- solution:end -->

<!-- solution:start -->

### Solution 2

<!-- tabs:start -->

#### Python3

```python
class Solution:
def abbreviateProduct(self, left: int, right: int) -> str:
cnt2 = cnt5 = 0
for x in range(left, right + 1):
while x % 2 == 0:
cnt2 += 1
x //= 2
while x % 5 == 0:
cnt5 += 1
x //= 5
c = cnt2 = cnt5 = min(cnt2, cnt5)
pre = suf = 1
gt = False
for x in range(left, right + 1):
suf *= x
while cnt2 and suf % 2 == 0:
suf //= 2
cnt2 -= 1
while cnt5 and suf % 5 == 0:
suf //= 5
cnt5 -= 1
if suf >= 1e10:
gt = True
suf %= int(1e10)
pre *= x
while pre > 1e5:
pre /= 10
if gt:
return str(int(pre)) + "..." + str(suf % int(1e5)).zfill(5) + 'e' + str(c)
return str(suf) + "e" + str(c)
```

<!-- tabs:end -->

<!-- solution:end -->

<!-- problem:end -->
Loading