leetcode 93 复原IP地址


前言

容易确定本题采用回溯法,挑战在于对各种情况做分类以及全面考虑一些特殊情况。

一、解题思路

回溯函数传入的参数包括:

  • 初始字符串s
  • s的当前索引位置index
  • 记录IP中某段当前累计的字符串cur
  • 用于存放IP中四个字段的vector<string>类型的容器combination

回溯函数中所有情况分类如下:

  • 字符串s中所有字符用尽即index=s.size(),检查combination的大小
    1)combination.size() = 4找到一组满足要求的IP组合,记录结果并返回
    2)combination.size() != 4函数直接返回
  • 若当前字段容器大小等于4但字符串中字符还未用尽,一定不符合要求,函数直接返回,即combination.size() == 4 && index<s.size()
  • 累计字符串cur的长度不会超过3,当长度超过3时不符合要求,函数直接返回,即cur.size() > 3
  • 当前位置index对应的字符可能有两种组合方式
    1)与当前段cur组合在一起作为IP地址中的同一段:将s[index]加入cur分段中,进入递归函数
    2)作为下一段的起始字符:需要将当前cur分段检验(是否位于0到255之间,且不含有前导0)后,压入combination容器后清空cur分段,再将s[index]加入新空白cur分段中。

二、代码实现

class Solution {
public:
	vector<string> res;
	    
	// 检验函数:检验分段是否满足要求(1)值位于0~255之间 (2)没有前导0
	//注意:该函数传入的cur不能为空字符串,需要在传入函数之前进行判断
	bool check(string cur){
	    int val = stoi(cur);
	    if(0 <= val && val <= 255){
	        if(cur[0] == '0' && cur.size() > 1) return false;
	        return true;
	    }
	    return false;
	}
	
	//回溯函数
	void backtrace(string& s, int index, string cur, vector<string> combination){
	    if(index == s.size()){
	    	//字符串遍历结束判断当前cur是否符合要求,若符合要求则压入分段记录容器中
	        if(!cur.empty() && check(cur)){
	            combination.push_back(cur);
	            cur.clear();
	        }
	        //找到一组IP地址,还原为字符串形式压入结果记录容器res中
	        if(combination.size() == 4 && cur.empty()){
	            string str;
	            for(int i = 0; i < 4; ++i) {
	                str += combination[i];
	                str.push_back('.');
	                }
	            str.pop_back();
	            res.push_back(str);
	            }
	        return;
	    }
	    
	    //提前结束回溯的情况
	    if((combination.size() == 4 && index < s.size()) || cur.size() > 3) 
	    	return;
	    	
	    cur.push_back(s[index]);
	    backtrace(s, index + 1, cur, combination);
	    
	    cur.pop_back();
	    if(!cur.empty() && check(cur)) {
	        combination.emplace_back(cur);
	        cur.clear();
	        cur.push_back(s[index]);
	        backtrace(s, index + 1, cur, combination);
	    }
	}
	
	// 算法入口函数
	vector<string> restoreIpAddresses(string s) {
	    backtrace(s, 0, "", {});
	    return res;
	}
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值