[JavaScript 刷题] Code Signal - 翻转括号内字符(reverseInParentheses)
Posted GoldenaArcher
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[JavaScript 刷题] Code Signal - 翻转括号内字符(reverseInParentheses)相关的知识,希望对你有一定的参考价值。
[javascript 刷题] Code Signal - 翻转括号内字符(reverseInParentheses)
题目地址:reverseInParentheses
题目
如下:
Write a function that reverses characters in (possibly nested) parentheses in the input string.
Input strings will always be well-formed with matching ()
s.
Example:
-
For
inputString = "(bar)"
, the output should bereverseInParentheses(inputString) = "rab"
; -
For
inputString = "foo(bar)baz"
, the output should bereverseInParentheses(inputString) = "foorabbaz"
; -
For
inputString = "foo(bar)baz(blim)"
, the output should bereverseInParentheses(inputString) = "foorabbazmilb"
; -
For
inputString = "foo(bar(baz))blim"
, the output should bereverseInParentheses(inputString) = "foobazrabblim"
.Because
"foo(bar(baz))blim"
becomes"foo(barzab)blim"
and then"foobazrabblim"
.
Input/Output:
-
[execution time limit] 4 seconds (js)
-
[input] string inputString
A string consisting of lowercase English letters and the characters ( and ). It is guaranteed that all parentheses in inputString form a regular bracket sequence.
Guaranteed constraints:
0 ≤ inputString.length ≤ 50
. -
[output] string
Return inputString, with all the characters that were in parentheses reversed.
解题思路
这道题和之前在 Leetcode 碰到的一个问标点符号的问题感觉很像,所以刚开始打算使用 Stack 去解决这个问题的,后来发现卡在这里了。
主要有以下几个难点:
-
对于内置函数的返回值不是很熟悉,平常使用 VSC 或者 IDE 开发的时候会打断点、
console.log()
,但是在做 OA 的时候就很麻烦主要不是很熟悉的函数有
array.slice()
,当只有一个参数 n n n 时,截取的是从 [ n , . . . , l e n g t h − 1 ] [n, ..., length - 1] [n,...,length−1] 的长度。不知道为什么错误的觉得截取的是[0, ..., n - 1]
-
过度依赖于之前刷的 Leetcode 的经验,觉得使用 Stack 可以一遍过,但是忽略了两道题的差异。
当时的想法是将
(
存在 Stack 中,遇到)
后就 pop 掉上一个的(
所对应的 index,转换(abcdefg)
中的字符串,再使用一个 counter 去修改原本的数组,以期一个迭代就能完成任务。如:
ab(foo)cd
ab
正常的迭代过去,遇到(foo)
时,进行翻转,获取oof
,再从下标 2 开始推回原字符串,修改为aboofo)cd
。最后迭代数组,当 stack 的长度为 0 时,将后续的值从 2 + r e v e r s e d S t r . l e n g t h 2 + reversedStr.length 2+reversedStr.length 下标开始添加。这个实现方法的问题就在于,当碰到嵌套字符串时就报错了。
现在想来,加一个检查,当 stack 为空时再去 append 或是 concat 可能会是一个更好的方案。
最终的解决方案还是采取了两个迭代:
-
翻转所有的字符串
这个基本上跟的就是原本题目的解决方案:
原本的题目:
"foo(bar(baz))blim"
根据存在 stack 中的值,首先会翻转最中间的一层:
"foo(bar(zab))blim"
随后翻转第二岑:
"foo(baz(rab))blim"
-
去除所有的括号
这个理解起来就比较简单了
因为要做迭代加上翻转,所以这题的时间复杂度为 O ( n 2 ) O(n^2) O(n2),我采用的这个方法空间复杂度为 O ( n ) O(n) O(n)。
使用 JavaScript 解题
function reverseInParentheses(inputString) {
const stack = [];
let inputList = inputString.split('');
for (let i = 0; i < inputList.length; i++) {
if (inputList[i] === '(') {
stack.push(i);
} else if (inputList[i] === ')') {
const begin = stack.pop();
const reversedSeq = reverseString(inputList.slice(begin + 1, i));
appendSubsequence(reversedSeq, inputList, begin + 1);
}
}
return inputList.filter((char) => char !== '(' && char !== ')').join('');
}
// reverse 和 append 可以合并为同一个函数,需要将 begin 和 i 作为参数传进来,就可以直接修改原有的数组
const reverseString = (sequence) => {
for (let i = 0; i < sequence.length / 2; i++) {
const endIndex = sequence.length - i - 1;
[sequence[i], sequence[endIndex]] = [sequence[endIndex], sequence[i]];
}
return sequence;
};
const appendSubsequence = (sequence, arr, begin) => {
let counter = 0;
while (counter < sequence.length) {
arr[begin++] = sequence[counter++];
}
};
// console.log(reverseInParentheses("(bar)"));
// console.log(reverseInParentheses("foo(bar)baz"));
// console.log(reverseInParentheses("foo(bar)baz(blim)"));
console.log(reverseInParentheses('foo(bar(baz))blim'));
以上是关于[JavaScript 刷题] Code Signal - 翻转括号内字符(reverseInParentheses)的主要内容,如果未能解决你的问题,请参考以下文章
[JavaScript 刷题] Code Signal - 形状面积(shapeArea)
[JavaScript 刷题] Code Signal - 幸运数(is lucky)
[JavaScript 刷题] Code Signal - 翻转括号内字符(reverseInParentheses)
[JavaScript 刷题] Code Signal - 相似数组(Are Similar?)