LeetCode-131. Split palindrome string-backtracking + pruning

131. Split palindrome

Title description

Give you a string s, please split s into some substrings so that each substring is a palindrome string. Return all possible splitting schemes for s.

A palindrome is a string that is read both forward and backward.

Example 1:

Input: s = "aab"
Output: [["a","a","b"],["aa","b"]]
Example 2:

Input: s = "a"
Output: [["a"]]

Problem-solving ideas

Insert picture description here

  1. Each node represents the remaining strings that have not been scanned, and the branch generated is to intercept the prefix of the remaining strings;

  2. When generating the prefix string, determine whether the prefix string is a palindrome.

  • If the prefix string is a palindrome, branches and nodes can be generated;
  • If the prefix string is not a palindrome, no branches and nodes will be generated. This step is a pruning operation.
  1. Settlement when the leaf node is an empty string. At this time, the path from the root node to the leaf node is a result in the result set. Use depth-first traversal to record all possible results.

  2. Use a path variable path to search, and use one path globally (note that a copy is generated during settlement), so after the recursive execution method ends, it needs to backtrack, that is, take out the elements added before the recursion;

  3. The path operation is only at the end of the list, so the appropriate data structure is the stack.

class Solution_131 {
    
    
    public List<List<String>> partition(String s) {
    
    
        int len = s.length();
        List<List<String>> res = new ArrayList<>();
        if (len == 0){
    
    
            return res;
        }
        Deque<String> stack = new ArrayDeque<>();
        char[] charArray = s.toCharArray();
        dfs(charArray,0,len,stack,res);
        return res;
    }

    /**
     *
     * @param charArray
     * @param index 起始字符的索引
     * @param len 字符串s的长度,可以设置为全局变量
     * @param path 记录从根节点到叶子节点的路径
     * @param res 记录所有的结果
     */
    private void dfs(char[] charArray, int index, int len, Deque<String> path, List<List<String>> res) {
    
    
        if (index == len){
    
    
            res.add(new ArrayList<>(path));
            return;
        }
        for (int i = index; i <len; i++){
    
    
            //因为截取字符串是消耗性能的,采用传子串的方式判断一个子串是否是回文子串
            if (!checkPalindrome(charArray,index,i)){
    
    
                continue;
            }
            path.addLast(new String(charArray,index,i+1-index));
            dfs(charArray,i+1,len,path,res);
            path.removeLast();
        }
    }

    /**
     * 采用动态规划,把回文子串的结果记录在一个表格里
     * @param charArray
     * @param left 子串的左边界,可以取到
     * @param right 子串的右边界,可以取到
     * @return
     */
    private boolean checkPalindrome(char[] charArray, int left, int right) {
    
    
        while (left < right){
    
    
            if (charArray[left] != charArray[right]){
    
    
                return false;
            }
            left++;
            right--;
        }
        return true;
    }


}

Guess you like

Origin blog.csdn.net/qq_35655602/article/details/115057256