zoukankan      html  css  js  c++  java
  • 131. 分割回文串

    131. 分割回文串

    题目链接:131. 分割回文串(中等)

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

    回文串 是正着读和反着读都一样的字符串。

    示例 1:

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

    示例 2:

    输入:s = "a"
    输出:[["a"]]

    提示:

    • 1 <= s.length <= 16

    • s 仅由小写英文字母组成

    解题思路

    我觉得本题最大的难点在于:不知道如何将切割问题抽象为组合问题。

    如下图所示,可以将切割问题抽象为一棵树形结构,for循环用来横向遍历,递归用来纵向遍历。同时递归函数参数需要 start,因为切割过的地方,不能重复切割,和组合问题也是保持一致的。从图中可以看出,当statr不小于s的长度时,就可以找到一组分割方案。当然在分割的过程中还需要判断分割产生的子串是否是回文。

    C++

    class Solution {
    public:
        vector<vector<string>> result;
        vector<string> path;
        void backTracking(string s, int start) {
            // 当 起始位置 不小于 s 的大小,说明已经找到了一组分割方案了
            if (start >= s.size()) {
                result.push_back(path);
                return;
            }
            for (int i = start; i < s.size(); i++) {
                // 判断将被截取的字符串[start,i]是不是回文
                // 如果是,则截取并保存,继续纵向遍历
                // 如果不是,则横向遍历
                bool flag = isPalindrome(s, start, i);
                if (flag) {
                    // substr(start, length) 返回一个从指定位置开始的指定长度的子字符串
                    // star 所需的子字符串的起始位置 字符串中的第一个字符的索引为 0
                    // lenght 在返回的子字符串中应包括的字符个数
                    string str = s.substr(start, i - start + 1);
                    path.push_back(str);
                    backTracking(s, i + 1); // // 纵向继续找i+1为起始位置的子串
                    path.pop_back(); // 回溯过程,弹出此次已填子串
                }
            }
        }
        //判断一个字符串是不是回文
        bool isPalindrome(string s, int i, int j) {
            while (i < j) {
                if (s[i] != s[j]) return false;
                i++; j--;
            }
            return true;
        }
        vector<vector<string>> partition(string s) {
           path.clear();
           result.clear();
           backTracking(s, 0);
           return result;
        }
    };

    JavaScript

    let path = [];
    let result = [];
    ​
    const backTracking = (s, start) => {
        if (start >= s.length) {
            result.push([...path]);
            return;
        }
    ​
        for (let i = start; i < s.length; i++) {
            if (isPalindrome(s, start, i)) {
                let str = s.substr(start, i - start + 1);
                path.push(str);
                backTracking(s, i + 1);
                path.pop();
            }
        }
    }
    ​
    const isPalindrome = (s, i, j) => {
        while (i < j) {
            if (s[i] != s[j]) return false;
            i++;
            j--;
        }
        return true;
    }
    ​
    var partition = function(s) {
        path = [];
        result = [];
        backTracking(s, 0);
        return result;
    };

     

  • 相关阅读:
    数据库基础(2)
    数据库基础
    多线程(3)
    多线程(2)
    多线程(1)
    并发编程(3)
    软件工程——个人总结
    软件工程第二次作业-结对编程
    软件工程第二次作业——结对编程心得体会
    软件工程第一次作业补充
  • 原文地址:https://www.cnblogs.com/wltree/p/15731241.html
Copyright © 2011-2022 走看看