1. 程式人生 > >93. Restore IP Addresses--back tracking -- 類比39 Combination Sum

93. Restore IP Addresses--back tracking -- 類比39 Combination Sum

93 給你 一串數字,讓你求出可能的IP 地址。

Input: "25525511135"
Output: ["255.255.11.135", "255.255.111.35"]

仔細分析一下這題和39題 幾乎完全一樣呀,39是給你 一個沒有重複陣列,可以重複使用數組裡的數字之和來組成 target.
Input: candidates = [2,3,6,7], target = 7,
A solution set is:
[
  [7],
  [2,2,3]
]

93題本質: 因為IP 地址只能是1~3位, 假設有一個數組 nums = {1,2,3} 表示每次選擇IP地址的長度 ,然後 從Nums裡可以用重複數字,一共取4次,當取得數字的sum = input 字串的長度 時,說明選擇的長度為合法的。
然後驗證該長度下IP 地址是否合法, 以下兩種為 非法情況: 1. IP>255 2. IP長度大於1位,但前面有0, 比如 05, 003.

為了便於理解,以及和 39題對照,定義了nums 陣列,這段code 只能排 67% , code 如下:
class Solution {
    public List<String> restoreIpAddresses(String s) {
        
        List<String> result = new ArrayList<>();
        int[] nums = {1,2,3};
        dfs(new ArrayList<Integer>(), nums, result, 0,0, s);
        return result;
    }
    
    private void dfs(List<Integer> list, int
[] nums, List<String> result, int depth, int sum, String s){ if(depth == 4 && sum == s.length()){ String ip = gen_ip_address(list, s); if(!ip.equals("-1")){ result.add(ip); return; } }
if(depth == 4 || sum > s.length()){ return; } for(int i=0; i< nums.length; i++){ sum += nums[i]; list.add(nums[i]); dfs(list,nums,result,depth+1, sum, s); sum -= nums[i]; list.remove(list.size()-1); } } private String gen_ip_address(List<Integer> list, String s){ int start = 0; String res = ""; for(int i=0; i<4; i++){ String si = s.substring(start, start+list.get(i)); start += list.get(i); if(Integer.valueOf(si) >255) return "-1"; if(list.get(i)>1 && si.charAt(0) == '0') return "-1"; if(i<3) res += si+"."; else res+= si; } return res; } }

 

去掉了 nums 並且用remain 代替sum, 可以排名95%: 

class Solution {
    public List<String> restoreIpAddresses(String s) {
        
        List<String> result = new ArrayList<>();
        dfs(new ArrayList<Integer>(),  result, 0,s.length(), s);
        return result;
    }
    
    private void dfs(List<Integer> list, List<String> result, int depth, int remain, String s){
        if(depth == 4 && remain == 0){
            String ip = gen_ip_address(list, s);
            if(!ip.equals("-1")){
                result.add(ip);
                return;
            }
        }
        
        if(depth == 4 ||  remain <0){
            return;
        }  
        for(int i=1; i<=3; i++){
            list.add(i);
            dfs(list,result,depth+1, remain-i, s);
            list.remove(list.size()-1);
        }
    }
    
    private String gen_ip_address(List<Integer> list, String s){  
        int start = 0;
        String res = "";
        for(int i=0; i<4; i++){
            String si = s.substring(start, start+list.get(i));
            start += list.get(i);
            
            if(Integer.valueOf(si) >255)
                return "-1";
            if(list.get(i)>1 && si.charAt(0) == '0')
                return "-1";
            if(i<3) res += si+".";
            else res+= si;
        } 
        return res;
    }
}