每天做个总结吧,坚持就是胜利!
/**
@date 2021-05-26
@description leetcode-1190: 反转每对括号间的子串
*/
壹(序)
leetcode的每日1题前几天都是困难,研究了一下没明白,今天可算是个中等了,虽然是个比较简单的中等,但是细致的理一下整体思路,也是会有收获的。
贰(题目描述)
leetcode1190. 反转每对括号间的子串:
给出一个字符串 s(仅含有小写英文字母和括号)。
请你按照从括号内到外的顺序,逐层反转每对匹配括号中的字符串,并返回最终的结果。
注意,您的结果中 不应 包含任何括号。 示例 1:
输入:s = "(abcd)" 输出:"dcba" 示例 2:
输入:s = "(u(love)i)" 输出:"iloveu" 示例 3:
输入:s = "(ed(et(oc))el)" 输出:"leetcode" 示例 4:
输入:s = "a(bcdefghijkl(mno)p)q" 输出:"apmnolkjihgfedcbq"
叁(思路)
- 刚开始理解的是遇到括号只反转一次,所以认为
"(u(love)i)"应该是返回"ievolu",仔细阅读题目后明白,是需要每次遇到括号就反转。 - 所以明白题意过后,这道题还是很简单的,每次遇到
()就反转里面的字符串,那么我只要找到每对(),然后反转这次()中的字符串,再进行一个递归操作,直到没有(); - 现在主要问题是如何找到成对的
(),首先确定的是,从内到外找,是比较容易的一种思路,所以第一个(必定是找字符串中的最后一个(,那与之成对的),可以在找到(后往后找,找到第一个)就行了; - 然后将这对
()里面的字符串反转,并拼接(前面和)后面的字符串形成新的字符串,进行递归调用; - 递归的边界,如果没有找到
(,便可确定已经没有()了,此时直接返回传入的字符串;
肆(代码)
/**
* @param {string} s
* @return {string}
*/
const reverseParentheses = (s) => {
const leftIndex = s.lastIndexOf('(');
if (leftIndex === -1) {
return s
}
const rightIndex = s.slice(leftIndex).indexOf(')') + leftIndex;
const left = s.slice(0, leftIndex);
const right = s.slice(rightIndex + 1);
return reverseParentheses(
`${left}${reverseStr(s.slice(leftIndex + 1, rightIndex))}${right}`
)
};
const reverseStr = (s) => s.split('').reverse().join('')
伍(优化)
如果是"(abcd)"这样的字符串,其实只需要直接反转()里面的内容即可,不需要后续操作,所以加一个判断,进行一个优化。
陆(最终代码)
/**
* @param {string} s
* @return {string}
*/
const reverseParentheses = (s) => {
const leftIndex = s.lastIndexOf('(');
if (leftIndex === -1) {
return s
}
const rightIndex = s.slice(leftIndex).indexOf(')') + leftIndex;
if (leftIndex === 0 && rightIndex === s.length - 1) {
return reverseStr(s.slice(1, rightIndex))
}
const left = s.slice(0, leftIndex);
const right = s.slice(rightIndex + 1);
return reverseParentheses(
`${left}${reverseStr(s.slice(leftIndex + 1, rightIndex))}${right}`
)
};
const reverseStr = (s) => s.split('').reverse().join('')