Skip to content

Commit 11f3e13

Browse files
committed
Add solution 1190
1 parent 315d4fa commit 11f3e13

27 files changed

+859
-600
lines changed

README.md

Lines changed: 414 additions & 413 deletions
Large diffs are not rendered by default.

leetcode/0080.Remove-Duplicates-from-Sorted-Array-II/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,6 @@ for (int i = 0; i < len; i++) {
5151

5252
## 解题思路
5353

54-
问题提示有序数组,一般最容易想到使用双指针的解法,双指针的关键点:移动两个指针的条件。
55-
在该题中移动的条件:快指针从头遍历数组,慢指针指向修改后的数组的末端,当慢指针指向倒数第二个数与快指针指向的数不相等时,才移动慢指针,同时赋值慢指针
56-
处理边界条件:当数组小于两个元素时,不做处理
54+
- 问题提示有序数组,一般最容易想到使用双指针的解法,双指针的关键点:移动两个指针的条件。
55+
- 在该题中移动的条件:快指针从头遍历数组,慢指针指向修改后的数组的末端,当慢指针指向倒数第二个数与快指针指向的数不相等时,才移动慢指针,同时赋值慢指针
56+
- 处理边界条件:当数组小于两个元素时,不做处理
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package leetcode
2+
3+
func reverseParentheses(s string) string {
4+
pair, stack := make([]int, len(s)), []int{}
5+
for i, b := range s {
6+
if b == '(' {
7+
stack = append(stack, i)
8+
} else if b == ')' {
9+
j := stack[len(stack)-1]
10+
stack = stack[:len(stack)-1]
11+
pair[i], pair[j] = j, i
12+
}
13+
}
14+
res := []byte{}
15+
for i, step := 0, 1; i < len(s); i += step {
16+
if s[i] == '(' || s[i] == ')' {
17+
i = pair[i]
18+
step = -step
19+
} else {
20+
res = append(res, s[i])
21+
}
22+
}
23+
return string(res)
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package leetcode
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
type question1190 struct {
9+
para1190
10+
ans1190
11+
}
12+
13+
// para 是参数
14+
// one 代表第一个参数
15+
type para1190 struct {
16+
s string
17+
}
18+
19+
// ans 是答案
20+
// one 代表第一个答案
21+
type ans1190 struct {
22+
one string
23+
}
24+
25+
func Test_Problem1190(t *testing.T) {
26+
27+
qs := []question1190{
28+
29+
{
30+
para1190{"(abcd)"},
31+
ans1190{"dcba"},
32+
},
33+
34+
{
35+
para1190{"(u(love)i)"},
36+
ans1190{"iloveu"},
37+
},
38+
39+
{
40+
para1190{"(ed(et(oc))el)"},
41+
ans1190{"leetcode"},
42+
},
43+
44+
{
45+
para1190{"a(bcdefghijkl(mno)p)q"},
46+
ans1190{"apmnolkjihgfedcbq"},
47+
},
48+
}
49+
50+
fmt.Printf("------------------------Leetcode Problem 1190------------------------\n")
51+
52+
for _, q := range qs {
53+
_, p := q.ans1190, q.para1190
54+
fmt.Printf("【input】:%v 【output】:%v\n", p, reverseParentheses(p.s))
55+
}
56+
fmt.Printf("\n\n\n")
57+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# [1190. Reverse Substrings Between Each Pair of Parentheses](https://leetcode.com/problems/reverse-substrings-between-each-pair-of-parentheses/)
2+
3+
4+
## 题目
5+
6+
You are given a string `s` that consists of lower case English letters and brackets.
7+
8+
Reverse the strings in each pair of matching parentheses, starting from the innermost one.
9+
10+
Your result should **not** contain any brackets.
11+
12+
**Example 1:**
13+
14+
```
15+
Input: s = "(abcd)"
16+
Output: "dcba"
17+
```
18+
19+
**Example 2:**
20+
21+
```
22+
Input: s = "(u(love)i)"
23+
Output: "iloveu"
24+
Explanation: The substring "love" is reversed first, then the whole string is reversed.
25+
```
26+
27+
**Example 3:**
28+
29+
```
30+
Input: s = "(ed(et(oc))el)"
31+
Output: "leetcode"
32+
Explanation: First, we reverse the substring "oc", then "etco", and finally, the whole string.
33+
```
34+
35+
**Example 4:**
36+
37+
```
38+
Input: s = "a(bcdefghijkl(mno)p)q"
39+
Output: "apmnolkjihgfedcbq"
40+
```
41+
42+
**Constraints:**
43+
44+
- `0 <= s.length <= 2000`
45+
- `s` only contains lower case English characters and parentheses.
46+
- It's guaranteed that all parentheses are balanced.
47+
48+
## 题目大意
49+
50+
给出一个字符串 s(仅含有小写英文字母和括号)。请你按照从括号内到外的顺序,逐层反转每对匹配括号中的字符串,并返回最终的结果。注意,您的结果中 不应 包含任何括号。
51+
52+
## 解题思路
53+
54+
- 本题最容易想到的思路是利用栈将每对括号里面的字符串入栈,当遇到 ")" 括号时出栈并逆序。由于用到了栈的数据结构,多层括号嵌套的问题也不用担心。这种边入栈出栈,逆序字符串的方法,时间复杂度是 O(n^2),有没有可能进一步降低时间复杂度呢?
55+
- 上述解法中,存在重复遍历的情况。扫描原字符串的时候,入栈出栈已经扫描了一次,在 ")" 括号出栈时,逆序又会扫一遍已经入栈的字符串。这部分重复遍历的过程可以优化掉。第一次循环先标记出逆序区间。例如遇到 "(" 的时候,入栈并记录下它的下标,当遇到 ")" 的时候,意味着这一对括号匹配上了,所以将 ")" 的下标和之前入栈 "(" 的下标交换。此次遍历将逆序区间标记出来了。再遍历一次,根据逆序区间逆序字符串。不在逆序区间的字符串正常 append。如果在逆序区间内的,逆序遍历,添加到最终结果字符串中。这样做,时间复杂度仅为 O(n)。具体实现见下面代码。
56+
57+
## 代码
58+
59+
```go
60+
package leetcode
61+
62+
func reverseParentheses(s string) string {
63+
pair, stack := make([]int, len(s)), []int{}
64+
for i, b := range s {
65+
if b == '(' {
66+
stack = append(stack, i)
67+
} else if b == ')' {
68+
j := stack[len(stack)-1]
69+
stack = stack[:len(stack)-1]
70+
pair[i], pair[j] = j, i
71+
}
72+
}
73+
res := []byte{}
74+
for i, step := 0, 1; i < len(s); i += step {
75+
if s[i] == '(' || s[i] == ')' {
76+
i = pair[i]
77+
step = -step
78+
} else {
79+
res = append(res, s[i])
80+
}
81+
}
82+
return string(res)
83+
}
84+
```

website/content/ChapterFour/0001~0099/0080.Remove-Duplicates-from-Sorted-Array-II.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ for (int i = 0; i < len; i++) {
6060

6161
## 解题思路
6262

63-
这道题和第 26 题很像。是第 26 题的加强版。这道题和第 283 题,第 27 题基本一致,283 题是删除 0,27 题是删除指定元素,这一题是删除重复元素,实质是一样的
64-
65-
这里数组的删除并不是真的删除,只是将删除的元素移动到数组后面的空间内,然后返回数组实际剩余的元素个数,OJ 最终判断题目的时候会读取数组剩余个数的元素进行输出
63+
- 问题提示有序数组,一般最容易想到使用双指针的解法,双指针的关键点:移动两个指针的条件
64+
- 在该题中移动的条件:快指针从头遍历数组,慢指针指向修改后的数组的末端,当慢指针指向倒数第二个数与快指针指向的数不相等时,才移动慢指针,同时赋值慢指针。
65+
- 处理边界条件:当数组小于两个元素时,不做处理
6666

6767
## 代码
6868

@@ -84,6 +84,7 @@ func removeDuplicates(nums []int) int {
8484

8585
```
8686

87+
8788
----------------------------------------------
8889
<div style="display: flex;justify-content: space-between;align-items: center;">
8990
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/0001~0099/0079.Word-Search/">⬅️上一页</a></p>

website/content/ChapterFour/1100~1199/1189.Maximum-Number-of-Balloons.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,5 @@ func maxNumberOfBalloons(text string) int {
7373
----------------------------------------------
7474
<div style="display: flex;justify-content: space-between;align-items: center;">
7575
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1100~1199/1185.Day-of-the-Week/">⬅️上一页</a></p>
76-
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1200~1299/1200.Minimum-Absolute-Difference/">下一页➡️</a></p>
76+
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1100~1199/1190.Reverse-Substrings-Between-Each-Pair-of-Parentheses/">下一页➡️</a></p>
7777
</div>
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# [1190. Reverse Substrings Between Each Pair of Parentheses](https://leetcode.com/problems/reverse-substrings-between-each-pair-of-parentheses/)
2+
3+
4+
## 题目
5+
6+
You are given a string `s` that consists of lower case English letters and brackets.
7+
8+
Reverse the strings in each pair of matching parentheses, starting from the innermost one.
9+
10+
Your result should **not** contain any brackets.
11+
12+
**Example 1:**
13+
14+
```
15+
Input: s = "(abcd)"
16+
Output: "dcba"
17+
```
18+
19+
**Example 2:**
20+
21+
```
22+
Input: s = "(u(love)i)"
23+
Output: "iloveu"
24+
Explanation: The substring "love" is reversed first, then the whole string is reversed.
25+
```
26+
27+
**Example 3:**
28+
29+
```
30+
Input: s = "(ed(et(oc))el)"
31+
Output: "leetcode"
32+
Explanation: First, we reverse the substring "oc", then "etco", and finally, the whole string.
33+
```
34+
35+
**Example 4:**
36+
37+
```
38+
Input: s = "a(bcdefghijkl(mno)p)q"
39+
Output: "apmnolkjihgfedcbq"
40+
```
41+
42+
**Constraints:**
43+
44+
- `0 <= s.length <= 2000`
45+
- `s` only contains lower case English characters and parentheses.
46+
- It's guaranteed that all parentheses are balanced.
47+
48+
## 题目大意
49+
50+
给出一个字符串 s(仅含有小写英文字母和括号)。请你按照从括号内到外的顺序,逐层反转每对匹配括号中的字符串,并返回最终的结果。注意,您的结果中 不应 包含任何括号。
51+
52+
## 解题思路
53+
54+
- 本题最容易想到的思路是利用栈将每对括号里面的字符串入栈,当遇到 ")" 括号时出栈并逆序。由于用到了栈的数据结构,多层括号嵌套的问题也不用担心。这种边入栈出栈,逆序字符串的方法,时间复杂度是 O(n^2),有没有可能进一步降低时间复杂度呢?
55+
- 上述解法中,存在重复遍历的情况。扫描原字符串的时候,入栈出栈已经扫描了一次,在 ")" 括号出栈时,逆序又会扫一遍已经入栈的字符串。这部分重复遍历的过程可以优化掉。第一次循环先标记出逆序区间。例如遇到 "(" 的时候,入栈并记录下它的下标,当遇到 ")" 的时候,意味着这一对括号匹配上了,所以将 ")" 的下标和之前入栈 "(" 的下标交换。此次遍历将逆序区间标记出来了。再遍历一次,根据逆序区间逆序字符串。不在逆序区间的字符串正常 append。如果在逆序区间内的,逆序遍历,添加到最终结果字符串中。这样做,时间复杂度仅为 O(n)。具体实现见下面代码。
56+
57+
## 代码
58+
59+
```go
60+
package leetcode
61+
62+
func reverseParentheses(s string) string {
63+
pair, stack := make([]int, len(s)), []int{}
64+
for i, b := range s {
65+
if b == '(' {
66+
stack = append(stack, i)
67+
} else if b == ')' {
68+
j := stack[len(stack)-1]
69+
stack = stack[:len(stack)-1]
70+
pair[i], pair[j] = j, i
71+
}
72+
}
73+
res := []byte{}
74+
for i, step := 0, 1; i < len(s); i += step {
75+
if s[i] == '(' || s[i] == ')' {
76+
i = pair[i]
77+
step = -step
78+
} else {
79+
res = append(res, s[i])
80+
}
81+
}
82+
return string(res)
83+
}
84+
```
85+
86+
87+
----------------------------------------------
88+
<div style="display: flex;justify-content: space-between;align-items: center;">
89+
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1100~1199/1189.Maximum-Number-of-Balloons/">⬅️上一页</a></p>
90+
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1200~1299/1200.Minimum-Absolute-Difference/">下一页➡️</a></p>
91+
</div>

website/content/ChapterFour/1200~1299/1200.Minimum-Absolute-Difference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,6 @@ func minimumAbsDifference(arr []int) [][]int {
7979

8080
----------------------------------------------
8181
<div style="display: flex;justify-content: space-between;align-items: center;">
82-
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1100~1199/1189.Maximum-Number-of-Balloons/">⬅️上一页</a></p>
82+
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1100~1199/1190.Reverse-Substrings-Between-Each-Pair-of-Parentheses/">⬅️上一页</a></p>
8383
<p><a href="https://books.halfrost.com/leetcode/ChapterFour/1200~1299/1201.Ugly-Number-III/">下一页➡️</a></p>
8484
</div>

0 commit comments

Comments
 (0)