1. 程式人生 > 其它 >02.字串分割

02.字串分割

131.分割回文串

給定一個字串 s,將 s 分割成一些子串,使每個子串都是迴文串。

返回 s 所有可能的分割方案。

示例: 輸入:"aab" 輸出: [ ["aa","b"], ["a","a","b"] ]

  • 切割問題可以抽象為組合問題
  • 如何模擬那些切割線
  • 切割問題中遞迴如何終止
  • 在遞迴迴圈中如何擷取子串
  • 如何判斷迴文
class Solution {
    List<List<String>> ans=new ArrayList<>();
    List<String> path=new ArrayList<>();
    
public List<List<String>> partition(String s) { process(s,0); return ans; } private void process(String s,int index){ if(index==s.length()){ ans.add(new ArrayList<>(path)); } for(int i=index;i<s.length();i++){ String cur
=s.substring(index,i+1); if(isHuiWen(cur)){ path.add(cur); process(s,i+1); path.remove(path.size()-1); } } } private boolean isHuiWen(String str){ int l=0; int r=str.length()-1; while(l<=r){
if(str.charAt(l)!=str.charAt(r)){ return false; } l++; r--; } return true; } }

93.復原IP地址

給定一個只包含數字的字串,復原它並返回所有可能的 IP 地址格式。

有效的 IP 地址 正好由四個整數(每個整數位於 0 到 255 之間組成,且不能含有前導 0),整數之間用 '.' 分隔。

例如:"0.1.2.201" 和 "192.168.1.1" 是 有效的 IP 地址,但是 "0.011.255.245"、"192.168.1.312" 和 "[email protected]" 是 無效的 IP 地址。

示例 1: 輸入:s = "25525511135" 輸出:["255.255.11.135","255.255.111.35"]

回溯三部曲

  • 遞迴引數
  • 遞迴終止條件
  • 單層搜尋的邏輯

判斷子串是否合法

主要考慮到如下三點:

  • 段位以0為開頭的數字不合法
  • 段位裡有非正整數字符不合法
  • 段位如果大於255了不合法
class Solution {

    List<String> result = new ArrayList<>();

    public List<String> restoreIpAddresses(String s) {
        if (s.length() > 12) return result; // 算是剪枝了
        backTrack(s, 0, 0);
        return result;
    }

    // startIndex: 搜尋的起始位置, pointNum:新增逗點的數量
    private void backTrack(String s, int startIndex, int pointNum) {
        if (pointNum == 3) {// 逗點數量為3時,分隔結束
            // 判斷第四段⼦字串是否合法,如果合法就放進result中
            if (isValid(s,startIndex,s.length()-1)) {
                result.add(s);
            }
            return;
        }
        for (int i = startIndex; i < s.length(); i++) {
            if (isValid(s, startIndex, i)) {
                s = s.substring(0, i + 1) + "." + s.substring(i + 1);    //在str的後⾯插⼊⼀個逗點
                System.out.println(s);
                pointNum++;
                backTrack(s, i + 2, pointNum);// 插⼊逗點之後下⼀個⼦串的起始位置為i+2
                pointNum--;// 回溯
                s = s.substring(0, i + 1) + s.substring(i + 2);// 回溯刪掉逗點
                //System.out.println(s);
            } else {
                break;
            }
        }
    }

    // 判斷字串s在左閉⼜閉區間[start, end]所組成的數字是否合法
    private Boolean isValid(String s, int start, int end) {
        if (start > end) {
            return false;
        }
        if (s.charAt(start) == '0' && start != end) { // 0開頭的數字不合法
            return false;
        }
        int num = 0;
        for (int i = start; i <= end; i++) {
            if (s.charAt(i) > '9' || s.charAt(i) < '0') { // 遇到⾮數字字元不合法
                return false;
            }
            num = num * 10 + (s.charAt(i) - '0');
            if (num > 255) { // 如果⼤於255了不合法
                return false;
            }
        }
        return true;
    }
}