LeetCode93. 復原 IP 地址
阿新 • • 發佈:2021-06-18
LeetCode93. 復原 IP 地址
題目描述
/** * * 給定一個只包含數字的字串,用以表示一個 IP 地址, * 返回所有可能從 s 獲得的 有效 IP 地址 。你可以按任何順序返回答案。 * <p> * 有效 IP 地址 正好由四個整數(每個整數位於 0 到 255 之間組成,且不能含有前導 0), * 整數之間用 '.' 分隔。 * <p> * 例如:"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址, * 但是 "0.011.255.245"、"192.168.1.312" 和 "[email protected]" 是 無效 IP 地址。 * */
思路分析
- 復原IP地址,即給定一個數字字串,按照IP地址規則將其復原為多個滿足條件的IP地址
- 很容易想到遞迴 + 回溯的方法
- 定義一個大小為4 的全域性陣列,用於儲存IP地址的每一段,因此還需要一個索引記錄是那一段
- 使用深度優先的方式,即遍歷字串,選擇一個滿足條件的數字字串作為IP地址的第一段,等條件不滿足或找到滿足的後再回溯尋找第一個滿足的其他字串,然後從未選擇的字串開始,依次再選擇第二段,第二段仍然有很多選擇,先選擇一個,等條件不滿足或找到滿足的後再回溯,直至選擇到最後一段
- 不斷的遞迴 + 回溯,直到找到所有滿足的或者篩選掉所有不滿足的
- 遞迴結束的條件為儲存每一段的陣列中都儲存了滿足格式的字串,並且字串全部遍歷結束,說明找到滿足IP遞迴規則的,則結束
- 或者陣列已滿,但是字串還沒有遍歷完,說明不滿足
- 還要考慮字串的某一位為零的情況,則直接將零作為單獨的一段即可
- 其他正常情況遞迴+回溯即可
- 原始碼見下
原始碼及分析
//表示總共將字串分為4段 static final int SEG_COUNT = 4; //建立集合儲存結果 List<String> list = new ArrayList<>(); //建立陣列儲存每一段的元素 int[] segments = new int[SEG_COUNT]; public List<String> restoreIpAddresses(String s) { dfs(s,0,0); return list; } /** * 從字串s的start位置開始尋找下一段的元素 * * @param s 字串 * @param seg 表示第幾段 * @param start 下一段開始位置索引 */ public void dfs(String s, int seg, int start) { //如果找到了四段ip並且遍歷完了字串,那麼就是一種答案 if (seg == SEG_COUNT){ if (start == s.length()){ //走到這一步說明segments陣列中已經存在一個滿足要求的答案,將其拼接轉成字串即可 StringBuffer ipAddress = new StringBuffer(); for (int i = 0; i < SEG_COUNT; i++) { //拼接字串 ipAddress.append(segments[i]); //拼接 . if (i != SEG_COUNT - 1){ ipAddress.append('.'); } } //將拼接後的結果新增到集合中 list.add(ipAddress.toString()); } //找到一個後繼續回溯 return; } //如果還沒找到4段IP就已經遍歷完了字串,那麼提前回溯 if (start == s.length()){ return; } //由於前導不能為零,如果遇到零,只能將0作為這一段的ip if (s.charAt(start) == '0') { segments[seg] = 0; dfs(s, seg + 1, start + 1); } //正常情況下,列舉每一種可能性並遞迴 //定義變數儲存每一段的結果 int address = 0; //從start開始遍歷,直到遍歷完字串 for (int i = start; i < s.length(); i++) { //先將每一段的字元轉為數字 address = address * 10 + (s.charAt(i) - '0'); //判斷當前段的地址是否滿足條件,如果滿足,則遞迴判斷下一段,否則結束 if (address > 0 && address <= 255) { segments[seg] = address; dfs(s, seg + 1, i + 1); }else { break; } } }