@@ -6,43 +6,45 @@ Tag : 「双端队列」、「栈」
66
77
88
9- 10- 给出一个字符串 s(仅含有小写英文字母和括号)。
9+ 给出一个字符串 ` s ` (仅含有小写英文字母和括号)。
1110
1211请你按照从括号内到外的顺序,逐层反转每对匹配括号中的字符串,并返回最终的结果。
1312
1413注意,您的结果中 不应 包含任何括号。
1514
16- 1715示例 1:
1816```
1917输入:s = "(abcd)"
18+
2019输出:"dcba"
2120```
2221示例 2:
2322```
2423输入:s = "(u(love)i)"
24+
2525输出:"iloveu"
2626```
2727示例 3:
2828```
2929输入:s = "(ed(et(oc))el)"
30+
3031输出:"leetcode"
3132```
3233示例 4:
3334```
3435输入:s = "a(bcdefghijkl(mno)p)q"
36+
3537输出:"apmnolkjihgfedcbq"
3638```
3739
3840提示:
39- * 0 <= s.length <= 2000
40- * s 中只有小写英文字母和括号
41+ * $ 0 <= s.length <= 2000$
42+ * ` s ` 中只有小写英文字母和括号
4143* 我们确保所有括号都是成对出现的
4244
4345---
4446
45- ### 基本分析
47+ ### 双端队列
4648
4749根据题意,我们可以设计如下处理流程:
4850
@@ -54,16 +56,9 @@ Tag : 「双端队列」、「栈」
5456
5557可以发现,上述过程需要用到双端队列(或者栈,使用栈的话,需要在最后一步对取出字符串再进行一次翻转)。
5658
57- 在 Java 中,双端队列可以使用自带的 ` ArrayDeque ` , 也可以直接使用数组进行模拟。
58- 59- ---
60- 61- ### 语言自带双端队列
62- 63- ![ image.png] ( https://pic.leetcode-cn.com/1621991010-kJgICN-image.png )
59+ 在 ` Java ` 中,双端队列可以使用自带的 ` ArrayDeque ` , 也可以直接使用数组进行模拟。
6460
65- 66- 代码:
61+ 代码(使用 ` ArrayDeque ` ):
6762``` Java
6863class Solution {
6964 public String reverseParentheses (String s ) {
@@ -79,9 +74,7 @@ class Solution {
7974 path. append(d. pollLast());
8075 } else {
8176 d. pollLast();
82- for (int j = 0 ; j < path. length(); j++ ) {
83- d. addLast(path. charAt(j));
84- }
77+ for (int j = 0 ; j < path. length(); j++ ) d. addLast(path. charAt(j));
8578 break ;
8679 }
8780 }
@@ -95,53 +88,39 @@ class Solution {
9588 }
9689}
9790```
98- * 时间复杂度:每个 ` ( ` 字符只会进出队列一次;` ) ` 字符串都不会进出队列,也只会被扫描一次;分析的重点在于普通字符,可以发现每个普通字符进出队列的次数取决于其右边的 ` ) ` 的个数,最坏情况下每个字符右边全是右括号,因此复杂度可以当做 $O(n^2),ドル但实际计算量必然取不满 $n^2,ドル将普通字符的重复弹出均摊到整个字符串处理过程,可以看作是每个字符串都被遍历常数次,复杂度为 $O(n)$
99- * 空间复杂度:$O(n)$
100- 101- ---
102- 103- ### 数组模拟双端队列
104- 105- ![ image.png] ( https://pic.leetcode-cn.com/1621993297-rtTfzz-image.png )
106- 107- 代码:
91+ 代码(数组模拟双端队列):
10892``` Java
10993class Solution {
110- char [] deque = new char [2009 ];
111- int head = 0 , tail = - 1 ;
112- char [] path = new char [2009 ];
94+ int N = 2010 , he = 0 , ta = 0 ;
95+ char [] d = new char [N ], path = new char [N ];
11396 public String reverseParentheses (String s ) {
11497 int n = s. length();
11598 char [] cs = s. toCharArray();
11699 for (int i = 0 ; i < n; i++ ) {
117100 char c = cs[i];
118101 if (c == ' )' ) {
119102 int idx = 0 ;
120- while (tail >= head) {
121- if (deque[tail] == ' (' ) {
122- tail-- ;
123- for (int j = 0 ; j < idx; j++ ) {
124- deque[++ tail] = path[j];
125- }
103+ while (he < ta) {
104+ if (d[ta - 1 ] == ' (' && -- ta >= 0 ) {
105+ for (int j = 0 ; j < idx; j++ ) d[ta++ ] = path[j];
126106 break ;
127107 } else {
128- path[idx++ ] = deque[tail -- ];
108+ path[idx++ ] = d[ -- ta ];
129109 }
130110 }
131111 } else {
132- deque[ ++ tail ] = c;
112+ d[ta ++ ] = c;
133113 }
134114 }
135115 StringBuilder sb = new StringBuilder ();
136- while (tail >= head ) sb. append(deque[head ++ ]);
116+ while (he < ta ) sb. append(d[he ++ ]);
137117 return sb. toString();
138118 }
139119}
140120```
141121* 时间复杂度:每个 ` ( ` 字符只会进出队列一次;` ) ` 字符串都不会进出队列,也只会被扫描一次;分析的重点在于普通字符,可以发现每个普通字符进出队列的次数取决于其右边的 ` ) ` 的个数,最坏情况下每个字符右边全是右括号,因此复杂度可以当做 $O(n^2),ドル但实际计算量必然取不满 $n^2,ドル将普通字符的重复弹出均摊到整个字符串处理过程,可以看作是每个字符串都被遍历常数次,复杂度为 $O(n)$
142122* 空间复杂度:$O(n)$
143123
144- 145124---
146125
147126### 最后
0 commit comments