LeetCode - 解题笔记 - 93 - Restore IP Addresses

Solution 1

一开始我以为是动态规划,后来反应过来要求输出所有的结果,那就必须要搜索了。

终止策略有:

  1. 已经有4个满足要求的分段,所有的数字分配完毕,找到一个答案
  2. 已经有4个满足要求的分段,尚有数字未分配,非有效答案(这一步可以直接替代超长字符串剪枝)
  3. 不足4个满足要求的分段,但所有数字分配完毕,非有效答案

搜索策略有:

  1. 如果当前向下搜索,第一个数字为0,那么只能将当前位作为一个分段向下搜索
  2. 否则,可以不断包括后续数字,直到和超过255(相对于硬性搜索三位,直接这么判断更简洁)
    时间复杂度: O ( 3 4 × 12 ) O(3^4 imes 12) O(34×12),原则来看搜索复杂度应该是 O ( N ! ) O(N!) O(N!)的,但是因为这道题的限制范围非常严格(最多检查12位,只能是4个分段),所以搜索深度只有4层,每层枚举量最多为3。 空间复杂度: O ( 1 ) O(1) O(1),不考虑最终答案的占用,中间仅维护常数个状态量
class Solution {
          
   
public:
    vector<string> restoreIpAddresses(string s) {
          
   
        vector<string> ans;
        vector<int> segments;
        this->dfs(ans, segments, s, 0);
        
        return ans;
    }
    
private:
    void dfs(vector<string> & ans, vector<int> & segments, string & s, int pos) {
          
   
        if (segments.size() == 4) {
          
   
            if (pos == s.size()) {
          
   
                ans.emplace_back(this->makeIPAddress(segments));
            }
            
            return;
        }
      
        if (pos == s.size()) {
          
   
            return;
        }
        
        
        if (s[pos] == 0) {
          
   
            segments.push_back(0);
            this->dfs(ans, segments, s, pos + 1);
            segments.pop_back();
        } else {
          
   
            int segment = 0;
            for (int offset = pos; offset < s.size(); offset++) {
          
   
                segment = segment * 10 + (s[offset] - 48);
                if (segment < 256) {
          
   
                    segments.push_back(segment);
                    this->dfs(ans, segments, s, offset + 1);  
                    segments.pop_back();
                } else {
          
   
                    break;
                }
                
            }
        }
    }
    
    string makeIPAddress(vector<int> & segments) {
          
   
        string ans;
        for (int i = 0; i < segments.size(); i++) {
          
   
            ans += to_string(segments[i]);
            if (i < segments.size() - 1) {
          
   
                ans += .;
            }
        }
        
        return ans;
    }
};

Solution 2

Solution 1的Python实现

class Solution:
    def restoreIpAddresses(self, s: str) -> List[str]:
        ans = list()
        segments = list()
        
        def dfs(pos):
            nonlocal segments, ans
            if len(segments) == 4:
                if pos == len(s):
                    ans.append(..join(segments))
                
                return
            
            if pos == len(s): return
            
            if s[pos] == 0 :
                segments.append(0)
                dfs(pos + 1)
                segments.pop()
            else:
                for offset in range(pos, len(s)):
                    if int(s[pos:offset + 1]) < 256:
                        segments.append(s[pos:offset + 1])
                        dfs(offset + 1)
                        segments.pop()
                    else: break
        
        dfs(0)
        
        return ans
经验分享 程序员 微信小程序 职场和发展