leetcode 7

给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。

有效的 IP 地址正好由四个整数(每个整数位于 0 到 255 之间组成),整数之间用 '.' 分隔。

 

示例:

输入: "25525511135"
输出: ["255.255.11.135", "255.255.111.35"]
class Solution {
private:
    static constexpr int SEG_COUNT = 4;
//constexpr和const类似,只不过编译器会检查表达式右侧的是否为常数值,如果不是则会报错
private:
    vector<string> ans;
    vector<int> segments;
public:
    void dfs(const string&s,int segId,int segStart)
    {//找到四段IP地址,并且遍历完字符串,则找到一种答案
       if(segId == SEG_COUNT){
           if(segStart == s.size())
           {
               string ipAddr;
               for(int i=0;i<SEG_COUNT;i++){
                   ipAddr += to_string(segments[i]);
                   if(i != SEG_COUNT - 1){
                       ipAddr += ".";//最后一段末尾不需要加"."
                   }
               }
               ans.push_back(move(ipAddr));
//std::move函数可以以非常简单的方式将左值引用转换为右值引用
//vector::push_back 等这类函数时,会对参数的对象进行复制,连数据也会复制.这就会造成对象内存的额外创建
//本来原意是想把参数push_back进去就行了,通过std::move,可以避免不必要的拷贝操作。
           }
           return;
       }
       if(segStart == s.size())
       {//没有找到四段id便遍历完整个字符串,说明找到的不合法,需要向前回溯
           return;
       }
       if (s[segStart] == '0')
       {//不存在前导0的情况,如果段落的开始是0的话,则整段均为0
         segments[segId] =0;
         dfs(s,segId+1,segStart+1);
       }
       //枚举每一种可能的情况
       int addr = 0;
       for(int segEnd = segStart;segEnd<s.size();segEnd++){//初始segStart为0找到合法的几段后,递归求解
           addr = addr*10+(s[segEnd] - '0');
           if(addr >0 && addr <= 0xFF){
               segments[segId] = addr;//找到一个合法的一小段
               dfs(s,segId+1,segEnd+1);//段落数加一,开始位置为上一个段的下一个字符
           }else{
               break;//找到的一小段超过255
           }
       }
    }
    vector<string> restoreIpAddresses(string s) {
       segments.resize(SEG_COUNT);
       dfs(s,0,0);
       return ans;
    }
};

注意:树深度搜索递归的练习,找准递归返回的条件和递归的规则,逐步进行书写。

 
posted @ 2020-08-09 09:43  zmachine  阅读(128)  评论(0编辑  收藏  举报