Add solution 1190

This commit is contained in:
YDZ
2021-05-27 11:00:10 +08:00
parent 315d4fa8d8
commit 11f3e13688
27 changed files with 859 additions and 600 deletions

View File

@ -51,6 +51,6 @@ for (int i = 0; i < len; i++) {
## 解题思路
问题提示有序数组,一般最容易想到使用双指针的解法,双指针的关键点:移动两个指针的条件。
在该题中移动的条件:快指针从头遍历数组,慢指针指向修改后的数组的末端,当慢指针指向倒数第二个数与快指针指向的数不相等时,才移动慢指针,同时赋值慢指针
处理边界条件:当数组小于两个元素时,不做处理
- 问题提示有序数组,一般最容易想到使用双指针的解法,双指针的关键点:移动两个指针的条件。
- 在该题中移动的条件:快指针从头遍历数组,慢指针指向修改后的数组的末端,当慢指针指向倒数第二个数与快指针指向的数不相等时,才移动慢指针,同时赋值慢指针
- 处理边界条件:当数组小于两个元素时,不做处理

View File

@ -0,0 +1,24 @@
package leetcode
func reverseParentheses(s string) string {
pair, stack := make([]int, len(s)), []int{}
for i, b := range s {
if b == '(' {
stack = append(stack, i)
} else if b == ')' {
j := stack[len(stack)-1]
stack = stack[:len(stack)-1]
pair[i], pair[j] = j, i
}
}
res := []byte{}
for i, step := 0, 1; i < len(s); i += step {
if s[i] == '(' || s[i] == ')' {
i = pair[i]
step = -step
} else {
res = append(res, s[i])
}
}
return string(res)
}

View File

@ -0,0 +1,57 @@
package leetcode
import (
"fmt"
"testing"
)
type question1190 struct {
para1190
ans1190
}
// para 是参数
// one 代表第一个参数
type para1190 struct {
s string
}
// ans 是答案
// one 代表第一个答案
type ans1190 struct {
one string
}
func Test_Problem1190(t *testing.T) {
qs := []question1190{
{
para1190{"(abcd)"},
ans1190{"dcba"},
},
{
para1190{"(u(love)i)"},
ans1190{"iloveu"},
},
{
para1190{"(ed(et(oc))el)"},
ans1190{"leetcode"},
},
{
para1190{"a(bcdefghijkl(mno)p)q"},
ans1190{"apmnolkjihgfedcbq"},
},
}
fmt.Printf("------------------------Leetcode Problem 1190------------------------\n")
for _, q := range qs {
_, p := q.ans1190, q.para1190
fmt.Printf("【input】:%v 【output】:%v\n", p, reverseParentheses(p.s))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,84 @@
# [1190. Reverse Substrings Between Each Pair of Parentheses](https://leetcode.com/problems/reverse-substrings-between-each-pair-of-parentheses/)
## 题目
You are given a string `s` that consists of lower case English letters and brackets.
Reverse the strings in each pair of matching parentheses, starting from the innermost one.
Your result should **not** contain any brackets.
**Example 1:**
```
Input: s = "(abcd)"
Output: "dcba"
```
**Example 2:**
```
Input: s = "(u(love)i)"
Output: "iloveu"
Explanation: The substring "love" is reversed first, then the whole string is reversed.
```
**Example 3:**
```
Input: s = "(ed(et(oc))el)"
Output: "leetcode"
Explanation: First, we reverse the substring "oc", then "etco", and finally, the whole string.
```
**Example 4:**
```
Input: s = "a(bcdefghijkl(mno)p)q"
Output: "apmnolkjihgfedcbq"
```
**Constraints:**
- `0 <= s.length <= 2000`
- `s` only contains lower case English characters and parentheses.
- It's guaranteed that all parentheses are balanced.
## 题目大意
给出一个字符串 s仅含有小写英文字母和括号。请你按照从括号内到外的顺序逐层反转每对匹配括号中的字符串并返回最终的结果。注意您的结果中 不应 包含任何括号。
## 解题思路
- 本题最容易想到的思路是利用栈将每对括号里面的字符串入栈,当遇到 ")" 括号时出栈并逆序。由于用到了栈的数据结构,多层括号嵌套的问题也不用担心。这种边入栈出栈,逆序字符串的方法,时间复杂度是 O(n^2),有没有可能进一步降低时间复杂度呢?
- 上述解法中,存在重复遍历的情况。扫描原字符串的时候,入栈出栈已经扫描了一次,在 ")" 括号出栈时,逆序又会扫一遍已经入栈的字符串。这部分重复遍历的过程可以优化掉。第一次循环先标记出逆序区间。例如遇到 "(" 的时候,入栈并记录下它的下标,当遇到 ")" 的时候,意味着这一对括号匹配上了,所以将 ")" 的下标和之前入栈 "(" 的下标交换。此次遍历将逆序区间标记出来了。再遍历一次,根据逆序区间逆序字符串。不在逆序区间的字符串正常 append。如果在逆序区间内的逆序遍历添加到最终结果字符串中。这样做时间复杂度仅为 O(n)。具体实现见下面代码。
## 代码
```go
package leetcode
func reverseParentheses(s string) string {
pair, stack := make([]int, len(s)), []int{}
for i, b := range s {
if b == '(' {
stack = append(stack, i)
} else if b == ')' {
j := stack[len(stack)-1]
stack = stack[:len(stack)-1]
pair[i], pair[j] = j, i
}
}
res := []byte{}
for i, step := 0, 1; i < len(s); i += step {
if s[i] == '(' || s[i] == ')' {
i = pair[i]
step = -step
} else {
res = append(res, s[i])
}
}
return string(res)
}
```