leetcode-1190: 反转每对括号间的子串

570 阅读2分钟

每天做个总结吧,坚持就是胜利!

    /**
        @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"

叁(思路)

  1. 刚开始理解的是遇到括号只反转一次,所以认为"(u(love)i)" 应该是返回"ievolu" ,仔细阅读题目后明白,是需要每次遇到括号就反转。
  2. 所以明白题意过后,这道题还是很简单的,每次遇到()就反转里面的字符串,那么我只要找到每对(),然后反转这次()中的字符串,再进行一个递归操作,直到没有()
  3. 现在主要问题是如何找到成对的(),首先确定的是,从内到外找,是比较容易的一种思路,所以第一个(必定是找字符串中的最后一个(,那与之成对的),可以在找到(后往后找,找到第一个)就行了;
  4. 然后将这对()里面的字符串反转,并拼接(前面和)后面的字符串形成新的字符串,进行递归调用;
  5. 递归的边界,如果没有找到(,便可确定已经没有()了,此时直接返回传入的字符串;

肆(代码)

/**
 * @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('')