1 93. 复原 IP 地址
也是类似前一天的分割回文串。可以用我的字符之间0101的思路,也可以直接用[start_idx,i]选取子串的方法,选取后者,代码简洁一点:
class Solution {
public:
vector<string> ans;
string path;
void dfs(int u,int start_idx,string s)
{
if(u == 4 && start_idx == s.size())
{
string tmp_ans = path;
tmp_ans.pop_back();
ans.push_back(tmp_ans);
return;
}
for(int i = start_idx; i < s.size() && i - start_idx <= 2;i++)
{
string tmp = s.substr(start_idx, i - start_idx + 1);
int tmp_int = 0;
for(int j = 0; j < tmp.size();j++)
{
tmp_int += (tmp[j] - '0');
if(j != tmp.size()-1)tmp_int*=10;
}
if(tmp.size() > 1 && tmp[0] == '0' || tmp_int > 255)continue;
else
{
path += (tmp+'.');
dfs(u+1,i+1,s);
path.erase(path.size() - (tmp.size()+1));
}
}
}
vector<string> restoreIpAddresses(string s) {
dfs(0,0,s);
return ans;
}
};
2 78. 子集
我自己的做法:在dfs外面套一个for循环。
class Solution {
public:
vector<vector<int> > ans;
vector<int> path;
bool vis[20];
void dfs(int u,int k,int startidx,vector<int>& nums)
{
if(u == k + 1)
{
ans.push_back(path);
return;
}
for(int i = startidx; i < nums.size();i++)
{
if(!vis[i])
{
path.push_back(nums[i]);
vis[i] = 1;
dfs(u+1,k,i+1,nums);
vis[i] = 0;
path.pop_back();
}
}
}
vector<vector<int>> subsets(vector<int>& nums) {
int max_num = nums.size();
for(int k = 0; k <= max_num; k++)
dfs(0,k,0,nums);
vector<int> tmp;
ans.push_back(tmp);
return ans;
}
};
看了carl的代码,发现我的写法虽然过了但是过于冗余,外面的for循环就是多余的,可以理解为:
子集是收集树形结构中树的所有节点的结果。而组合问题、分割问题是收集树形结构中叶子节点的结果。
所以可以写出这样的代码:
class Solution {
public:
vector<vector<int>> ans;
vector<int> path;
void dfs(int start_idx,vector<int>& nums)
{
ans.push_back(path);
if(start_idx == nums.size())return;
for(int i = start_idx; i < nums.size();i++)
{
path.push_back(nums[i]);
dfs(i+1,nums);
path.pop_back();
}
}
vector<vector<int>> subsets(vector<int>& nums) {
dfs(0,nums);
return ans;
}
};
3 90. 子集 II
本题就是前一题和这一篇中40. 组合总和 II 的结合体,主要是40. 组合总和 II 。
AC代码:
class Solution {
public:
vector<vector<int>> ans;
vector<int> path;
// 同层不能重复取, 不同层可以重复取
bool vis[22];
void dfs(int start_idx,vector<int>& nums)
{
ans.push_back(path);
if(start_idx == nums.size())return;
for(int i = start_idx; i < nums.size();i++)
{
if(i != 0 && nums[i] == nums[i-1] && vis[nums[i]+10] == 0)continue;
vis[nums[i]+10] = 1;
path.push_back(nums[i]);
dfs(i+1,nums);
vis[nums[i]+10] = 0;
path.pop_back();
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(),nums.end());
dfs(0,nums);
return ans;
}
};