生活随笔
收集整理的這篇文章主要介紹了
复原ip地址
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
思路
意識到這是切割問題,「切割問題就可以使用回溯搜索法把所有可能性搜出來」
回溯三部曲
遞歸參數
在回溯算法:分割回文串中我們就提到切割問題類似組合問題。
startIndex一定是需要的,因為不能重復分割,記錄下一層遞歸分割的起始位置。
本題我們還需要一個變量pointNum,記錄添加逗點的數量。
遞歸終止條件
終止條件和回溯算法:分割回文串情況就不同了,本題明確要求只會分成4段,所以不能用切割線切到最后作為終止條件,而是分割的段數作為終止條件。
pointNum表示逗點數量,pointNum為3說明字符串分成了4段了。
然后驗證一下第四段是否合法,如果合法就加入到結果集里
單層搜索的邏輯
在回溯算法:分割回文串中已經講過在循環遍歷中如何截取子串。
在for (int i = startIndex; i < s.size(); i++)循環中 [startIndex, i]這個區間就是截取的子串,需要判斷這個子串是否合法。
如果合法就在字符串后面加上符號.表示已經分割。
如果不合法就結束本層循環,如圖中剪掉的分支:
然后就是遞歸和回溯的過程:
遞歸調用時,下一層遞歸的startIndex要從i+2開始(因為需要在字符串中加入了分隔符.),同時記錄分割符的數量pointNum 要 +1。
回溯的時候,就將剛剛加入的分隔符. 刪掉就可以了,pointNum也要-1。
判斷子串是否合法
考慮以下三點:
1、段位以0為開頭的數字不合法
2、段位里有非正整數字符不合法
3、段位如果大于255了不合法
class Solution {
private:vector
<string
> result
;void backtracking(string
& s
, int startIndex
, int pointNum
) {if (pointNum
== 3) { if (isValid(s
, startIndex
, s
.size() - 1)) {result
.push_back(s
);}return;}for (int i
= startIndex
; i
< s
.size(); i
++) {if (isValid(s
, startIndex
, i
)) { s
.insert(s
.begin() + i
+ 1 , '.'); pointNum
++;backtracking(s
, i
+ 2, pointNum
); pointNum
--; s
.erase(s
.begin() + i
+ 1); } else break; }}bool isValid(const string
& s
, int start
, int end
) {if (start
> end
) {return false;}if (s
[start
] == '0' && start
!= end
) { return false;}int num
= 0;for (int i
= start
; i
<= end
; i
++) {if (s
[i
] > '9' || s
[i
] < '0') { return false;}num
= num
* 10 + (s
[i
] - '0');if (num
> 255) { return false;}}return true;}
public:vector
<string
> restoreIpAddresses(string s
) {result
.clear();backtracking(s
, 0, 0);return result
;}
};
總結
以上是生活随笔為你收集整理的复原ip地址的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。