回溯法 LeetCode 17&93&131&46&77&39&79&200&130&51

树形问题

LeetCode 17. 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例:

输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

思路:

遍历头一个数字可能对应的所有字符,选取一个字符,递归遍历剩下数字可能的选取的字符组合

代码:

class Solution {
private:
	const string letterMap[10] ={
		" ",   //0 
		"",    //1 
		"abc", //2 
		"def", //3 
		"ghi", //4 
		"jkl", //5 
		"mno", //6 
		"pqrs",//7 
		"tuv", //8 
		"wxyz" //9 
	};
	vector<string> res;//结果 
	
	//s中保存了此时从digits[0...index-1]翻译得到的一个字母字符串
	//寻找和digits[index]匹配的字母,获得digits[0...index]翻译得到的解 
	void findCombination(const string &digits,int index, const string &s)
	{
		if(index==digits.size()) 
		{
			res.push_back(s);
			return;
		}
		char c = digits[index];//获得当前要匹配的字符
		string letters = letterMap[c-'0'];//获得当前字符可能的匹配的字母
		for(int i=0; i<letters.size(); i++)
		{
			findCombination(digits, index+1, s+letters[i]);//选择一个匹配字母,递归遍历剩下的
			// 回溯的过程就是回到当前递归时,s-letters[i] ,然后进入下一个循环,选择下一个可能匹配的字母 
		} 
		return;
	}
public:
    vector<string> letterCombinations(string digits) {
        res.clear();
		if( digits =="")
			return res;
		findCombination(digits,0,"");
		return res; 
    }
};

LeetCode 93. 复原IP地址

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

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

示例:

输入: "25525511135"
输出: ["255.255.11.135", "255.255.111.35"]
思路:

使用flag标记当前已经添加了几个点。

递归确定点的位置,index代表从当前坐标数字开始可以添加点,所以满足题意的就有三种情况,将点添加在s[index]后面,s[index+1]后面,s[index+2]后面。确定这三种方式的数值是否在0-255之间,如果满足,将点添加进去,继续递归确定剩下字符串点的位置。

递归结束是flag==3,说明已经在该字符串中添加了3个点,确定剩下的字符串的数值是否在0-255之间,如果在则分割成功,将结果保存下来。

class Solution {
private:
	 vector<string> res;
	 int flag;//记录现在添加了几个点了 
	 
	 //r存储s[0..index-1]的分割结果
	 //求s[0..index]的最佳分割结果 
	 void restoreIpAddresses(const string &s,int index,const string r)
	 {
	 	if(flag==3)
		{
			string str=s.substr(index);
			long long number = getNumber(str);
			if(str.size()>0 && number>=0 && number<=255)
				res.push_back(r+str);
			return;	
		} 
		//对于当前的字符串,最多可以将点添加在三个位置 
		for(int i=1; i<=3; i++)
		{
			if(index+i > s.size()) continue; //可能数组越界 
			string str=s.substr(index,i); //点分别加在index后面,后面一位,后面两位 
			long long number = getNumber(str);
			if(str.size()>0 && number>=0 && number<=255)
			{
				flag++;
				restoreIpAddresses(s,index+i,r+s.substr(index,i)+'.');
				flag--;//回溯 
			}
		}
		return;
	 }
	 //根据字符串s获取代表的数字 
	 long long getNumber(string s)
	 {
	 	//判断字符串是否合法 010
		if(s[0]=='0' && s.size()>1 ) return -1;  
	 	long long sum=0;
	 	for(long long i=0; i<s.size(); i++)
		{
		 	sum = sum*10+s[i]-'0';	
		} 
		return sum;
	 }
public:
    vector<string> restoreIpAddresses(string s) {
    	res.clear();
    	if(s=="" || s.size()>12)
    		ret
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值