LeetCode-131-分割回文串

雄獅虎豹 發表於 2021-12-04
LeetCode

分割回文串

題目描述:給你一個字串 s,請你將 s 分割成一些子串,使每個子串都是 迴文串 。返回 s 所有可能的分割方案。

迴文串 是正著讀和反著讀都一樣的字串。

示例說明請見LeetCode官網。

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/probl...
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

解法一:遞迴法

首先處理兩種特殊情況,如果字串為null,直接返回空結果集;如果字串的長度為1,則只有一種分割情況,直接返回這種情況。

當字串的長度大於1時,使用遞迴的方式處理,其中會使用一個判斷字串是否是迴文串的方法isHuiwen,遞迴過程如下:

  • 從字串的第一個字元開始判斷,引數有前面已經被分割槽的迴文串list、當前位置、當前要判斷的子串;
  • 首先判斷如果已經處理到字串的最後一個字元,如果當前分割槽字串是迴文串,則將當前分割槽字串新增到partitions,然後將之新增到結果集中,否則,直接返回;
  • 否則,首先判斷當前分割槽字串是否是迴文串,有兩種可能:

    • 如果是,則將當前分割槽字串新增到partitions,將下一個字元作為新的分割槽字串開始遞迴判斷;
    • 如果不是,將下一個字元新增到當前分割槽字串中,遞迴判斷。

最後,返回結果集。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class LeetCode_131 {
    // 結果集
    private static List<List<String>> result = new ArrayList<>();

    public static List<List<String>> partition(String s) {
        // 如果字串為null,直接返回空結果集
        if (s == null) {
            return new ArrayList<>();
        }
        // 如果字串只有一個字元,只可能有一個結果,直接返回
        if (s.length() == 1) {
            List<String> partition = new ArrayList<>();
            partition.add(s);
            result.add(partition);
            return result;
        }

        partition(s, 0, new ArrayList<>(), s.substring(0, 1));
        return result;
    }

    /**
     * 遞迴方法
     *
     * @param s            原始字串
     * @param pos          當前位置
     * @param partitions   當前位置之前已經被分割的迴文串
     * @param curPartition 當前分割槽字串
     */
    private static void partition(String s, int pos, List<String> partitions, String curPartition) {
        // 已經處理到字串的最後一個字元
        if (pos == s.length() - 1) {
            if (isHuiwen(curPartition)) {
                // 如果當前分割槽字串是迴文串,則將當前分割槽字串新增到partitions,然後將之新增到結果集中
                List<String> newPartitions = new ArrayList<>(Arrays.asList(new String[partitions.size()]));
                Collections.copy(newPartitions, partitions);
                newPartitions.add(curPartition);
                result.add(newPartitions);
            }
            return;
        }

        // 如果當前分割槽字串是迴文串,則將當前分割槽字串新增到partitions,然後遞迴判斷下一個字元
        if (isHuiwen(curPartition)) {
            List<String> newPartitions = new ArrayList<>(Arrays.asList(new String[partitions.size()]));
            Collections.copy(newPartitions, partitions);
            newPartitions.add(curPartition);
            partition(s, pos + 1, newPartitions, s.substring(pos + 1, pos + 2));
        }

        // 遞迴處理下一個字串
        partition(s, pos + 1, partitions, curPartition + s.substring(pos + 1, pos + 2));
    }

    /**
     * 判斷字串是否是迴文串
     *
     * @param str 字串
     * @return
     */
    private static boolean isHuiwen(String str) {
        if (str == null || str.length() < 2) {
            return true;
        }
        for (int i = 0; i < str.length() / 2; i++) {
            if (str.charAt(i) != str.charAt(str.length() - 1 - i)) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        for (List<String> string : partition("aab")) {
            System.out.println(string);
        }
    }
}
【每日寄語】 棄燕雀之小志,慕鴻鵠而高翔。