前端重拾算法数据结构一个月(12)

113 阅读2分钟

第十二天

今天早上快上公交车的时候突然通知说公司停电了(可恶早知道不起床了),所以来学习学习吧。今天学习的是回溯法的分割回文串问题。对应力扣上的131题。

第二十四题

回文串

那首先,先说明什么是回文串:

回文串 是正着读和反着读都一样的字符串。例如:aa,bbb,aba等等...

LeetCode131.分割回文串

给你一个字符串 s,请你将 s分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。

示例 1:

输入: s = "aab"
输出: [["a","a","b"],["aa","b"]]

思路: 这道题中,我们需要返回所有的可能性,而每一种可能性为一个数组,即最后应返回一个二维数组result,而也需要一个一维数组path来装每一种可能性,然后将其推入二维数组中。同样的三部曲走起来。第一步确定递归的参数和返回值。由于已经切割过的元素不能再被切割了,因此我们需要startIndex来控制每层递归应从哪个地方开始切割,接着还有一个参数就是字符串s了。那么第二步是确定终止条件,也就是到达叶子节点的位置,那么在这道题目里如何知道走到一条路径的最后了呢,就是当没有元素可以再被切割了也就是startIndex===s.length。而判断path中的数组是否满足全部为回文子串这一步骤,最好放在单层搜索逻辑中,这样可以少走一些递归函数。第三步就是写这个单层搜索逻辑了,首先里面要有一个判断子串是否回文的方法isPalindrome()。如果(startIndex到i)为回文子串的话,我们将它放进path中,然后继续往下走,如果不是那就不用继续往下走了直接continue。接着就是通常的递归backtracking()和回溯pop()了。

function partition(s: string): string[][] {
    const path:string[] = []
    const result:string[][] = []

    const isPalindrome = (str:string)=>{
        const reStr = str.split('').reverse().join('') //利用数组反转实现反转字符串
        return reStr===str
    }

    const backtracking = (startIndex:number)=>{
        if(startIndex===s.length){
            result.push(path.map(i=>i))
            return
        }
        for(let i=startIndex;i<s.length;i++){
            const ss = s.slice(startIndex,i+1)
            if(isPalindrome(ss)){
                path.push(ss)
            }else{
                continue
            }
            backtracking(i+1)
            path.pop()
        }
    }
    backtracking(0)

    return result
};

ok,补会儿觉去哈哈哈哈,晚上回来继续。