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; } };
注意:树深度搜索递归的练习,找准递归返回的条件和递归的规则,逐步进行书写。