93.复原IP地址
1.正常回溯就可以
我的做法是,先用vector存放ip,然后用函数vec2str()
转化为字符串。
其他的就是正常的回溯,有一些值得说的小细节:
- 因为最多就3位,所以切分时补充一个上限3位
- 出现01这种前导0不允许,要在判别时剔除
- 整数转字符串用
to_string()
,字符串转整数用stoi()
vector<string> res;
vector<int> ip;
string vec2str(vector<int>& vec)
{
string tmp;
for (auto& x : vec)
{
tmp.append(to_string(x));
tmp.append(".");
}
tmp.pop_back();
return tmp;
}
void backtracing(const string& s, int startIndex)
{
//段数多于4,不合法
if (ip.size() > 4) return;
//切割到底,段数等于4,合法
if (startIndex >= s.size() && ip.size() == 4)
{
res.push_back(vec2str(ip));
return;
}
for (int i = startIndex; i < s.size() && i < startIndex + 3; i++)
{
string tmp = s.substr(startIndex, i - startIndex + 1);
//合法性判别,位于0~255,没有前导0(除非只有0)
if (stoi(tmp) > -1 && stoi(tmp) < 256 && !(tmp.size() > 1 && tmp[0] == '0'))
{
ip.push_back(stoi(tmp));
backtracing(s, i + 1);
ip.pop_back();
}
else
{
continue;
}
}
}
vector<string> restoreIpAddresses(string s) {
res.clear();
ip.clear();
if (s.empty()) return res;
backtracing(s, 0);
return res;
}
2.代码随想录的方法
我简单看了下,用单独的数字记录段数,单独的函数判别合法性。
回溯也不是死套路,能跑就行啦~
78.子集
终于到了回溯的第三种常见问题——子集
集合问题与组合和切割不同的地方就是,它需要整棵树上所有的结点,这个我在切割回文的那道题也尝试过这么做,思路就是叶结点只负责返回,而每个回溯开始时都将此时结果添加到结果
其实终止条件可以不写,因为当startIndex
超过nums.size()
时,就不会再进入循环了
vector<vector<int>> res;
vector<int> path;
void backtracing(vector<int>& nums, int startIndex)
{
res.push_back(path);
if (startIndex >= nums.size()) return;
for (int i = startIndex; i < nums.size(); i++)
{
path.push_back(nums[i]);
backtracing(nums, i + 1);
path.pop_back();
}
}
vector<vector<int>> subsets(vector<int>& nums) {
res.clear();
path.clear();
backtracing(nums, 0);
return res;
}
90.子集II
这个题目又涉及到重复的问题,跟组合的重复其实很像,当出现了1,1,2
这种情况时,结果会出现两个1,2
,我们认为是不合法的。
这个解决方案也一样,在可选择范围内,同则跳过(nums得先排序)
vector<vector<int>> res;
vector<int> path;
void backtracing(vector<int>& nums, int startIndex)
{
res.push_back(path);
if (startIndex >= nums.size()) return;
for (int i = startIndex; i < nums.size(); i++)
{
if (i > startIndex && nums[i] == nums[i - 1]) continue;
path.push_back(nums[i]);
backtracing(nums, i + 1);
path.pop_back();
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
res.clear();
path.clear();
sort(nums.begin(), nums.end());
backtracing(nums, 0);
return res;
}