39. 组合总和
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:
输入:candidates = [2,3,6,7], target = 7,
所求解集为: [ [7], [2,2,3] ]
示例 2:
输入:candidates = [2,3,5], target = 8,
所求解集为: [ [2,2,2,2], [2,3,3], [3,5] ]
代码随想录的方法:
#include<bits/stdc++.h>
using namespace std;
vector<vector<int> > result; //注意最后两个> >之间要加上空格
vector<int> path;
void backtracking(int sum, int candidates[],int target,int startIndex)
{
if(sum > target) return ;
if(sum==target){
result.push_back(path);
return;
}
for(int i=startIndex ; i < 3 ; i++)
{
sum += candidates[i];
path.push_back(candidates[i]);
backtracking(sum,candidates,target,i);
sum -= candidates[i];
path.pop_back();
}
}
int main()
{
int candidates[3]={2,3,5};
int target = 8;
backtracking(0,candidates,target,0);
for(int i=0;i<result.size();i++){
vector<int> cmp = result[i];
for(int j = 0; j< cmp.size(); j ++){
cout<<cmp[j]<<" ";
}
cout<<endl;
}
}
赵*磊教的方法:
#include<bits/stdc++.h>
using namespace std;
vector<vector<int> > result; //注意最后两个> >之间要加上空格
vector<int> path;
int candidates[3]={2,3,5};
int target = 8;
void dfs(int sum, int now){
if(sum > target) return;
if(sum == target){
result.push_back(path);
return;
}
for(int i = now; i < 3; i ++){
path.push_back(candidates[i]);
dfs(sum+candidates[i], i);
path.pop_back();
}
}
int main()
{
dfs(0, 0);
for(int i=0;i<result.size();i++){
vector<int> cmp = result[i];
for(int j = 0; j< cmp.size(); j ++){
cout<<cmp[j]<<" ";
}
cout << endl;
}
}
如果每个数只能取一次:
//只能取一个数
#include<bits/stdc++.h>
using namespace std;
vector<vector<int> > result; //注意最后两个> >之间要加上空格
vector<int> path;
int candidates[3]={2,3,5};
int target = 8;
void dfs(int now, int sum){
if(sum == target){
result.push_back(path);
return;
}
if(now >= 3) return;
if(sum == target){
result.push_back(path);
return;
}
dfs(now+1, sum);
path.push_back(candidates[now]);
dfs(now+1, sum+candidates[now]);
path.pop_back();
}
int main()
{
dfs(0, 0);
for(int i=0;i<result.size();i++){
vector<int> cmp = result[i];
for(int j = 0; j< cmp.size(); j ++){
cout<<cmp[j]<<" ";
}
}
}
93.复原IP地址
给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
有效的 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。
例如:"0.1.2.201" 和 "192.168.1.1" 是 有效的 IP 地址,但是 "0.011.255.245"、"192.168.1.312" 和 "192.168@1.1" 是 无效的 IP 地址。
示例 1:
输入:s = "25525511135"
输出:["255.255.11.135","255.255.111.35"]
#include<bits/stdc++.h>
using namespace std;
string arr="25525511135";
vector<string> result;
bool check( string arr, int start ,int end)
{
if (arr[start]=='0' && start!= end) { // 0开头的数字不合法
return false;
}
if (start > end) {
return false;
}
int sum = 0;
for(int i=start ; i <= end ; i++){
sum = sum*10+(arr[i] - '0');
if(sum>255){
return false;
}
}
return true;
}
void backtracking(string arr,int startIndex,int count)
// startIndex: 搜索的起始位置 count :添加逗点的数量
{
if(count == 3){ // 逗点数量为3时,分隔结束
// 判断第四段子字符串是否合法,如果合法就放进result中
if(check(arr,startIndex,arr.size()-1)){
result.push_back(arr);
}
return;
}
for(int i = startIndex ;i < 11 ; i++)
{
if(check(arr,startIndex,i)){ // 判断 [startIndex,i] 这个区间的子串是否合法
arr.insert(arr.begin() + i + 1 , '.'); // 在i的后面插入一个逗点
count++;
backtracking(arr, i+2 ,count);
// 回溯
count--;
arr.erase(arr.begin()+i+1); // 回溯删掉逗点
}else{
break; // 不合法,直接结束本层循环
}
}
}
int main()
{
backtracking(arr,0,0);
for(int i=0; i < result.size() ; i++){
cout<<result[i]<<endl;
}
}