文章目录
131. 分割回文串
难度中等668收藏分享切换为英文接收动态反馈
给你一个字符串 s
,请你将 s
分割成一些子串,使每个子串都是 回文串 。返回 s
所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。
示例 1:
输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]
示例 2:
输入:s = "a"
输出:[["a"]]
思路: for控制着横向遍历
递归控制着纵向遍历
![](https://gitee.com/black-cat-loves-fawn/blogimage/raw/master/blogimage/20210331092337.jpeg)
除了上面的步骤以外剩下的就是剪枝了,在递归中continue
减去的是子树的某一个小分支;return
减去的是整个子树
class Solution {
public:
vector<vector<string>> res;
vector<vector<string>> partition(string s) {
vector<string> path;
backtrack(s,path,0);
return res;
}
void backtrack(string&s, vector<string>& path, int index) {
if(index == s.size()) {
res.push_back(path);
}
for(int i=index;i<s.size();i++) { // 这里其实是一个左闭右开的区间
if(IsPalindromes(s,index,i)){
path.push_back(s.substr(index,i-index+1));
} else {
continue;
}
backtrack(s,path,i+1) ;
path.pop_back();
}
}
bool IsPalindromes(string s,int begin,int end) {
if(begin==end) {
return true;
}
while(begin<end) {
if(s[begin]!=s[end]) {
return false;
}
begin++;
end--;
}
return true;
}
};
93. 复原 IP 地址
难度中等539收藏分享切换为英文接收动态反馈
给定一个只包含数字的字符串,用以表示一个 IP 地址,返回所有可能从 s
获得的 有效 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"]
示例 2:
输入:s = "0000"
输出:["0.0.0.0"]
示例 3:
输入:s = "1111"
输出:["1.1.1.1"]
示例 4:
输入:s = "010010"
输出:["0.10.0.10","0.100.1.0"]
示例 5:
输入:s = "101023"
输出:["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]
思路是一样的,分割次数为依据,分割三下后进行判断,后面剩余的数字是否符合255要求
class Solution {
public:
vector<string> res;
vector<string> restoreIpAddresses(string s) {
string path;
backtrack(s, path, 0, 0);
return res;
}
void backtrack(string&s, string path,int index,int count) {
if(count>3) {
return ;
}
if(count==3) {
string value = s.substr(index,s.size()-index);
// cout<<"count==3: "<<value<<endl;
if(value.empty()) {
return;
}
if(value.size()>1 && value[0]=='0') {
return;
}
long num = atoi(value.c_str());
// cout<<"num: "<<num<<endl;
if(num>255|| num<0) {
return ;
} else {
path+=value;
res.push_back(path);
}
return;
}
for(int i=index;i<s.size();i++) {
string value = s.substr(index,i-index+1);
if(value.empty()) {
continue;
}
if(value.size()>1 && value[0]=='0') {
return;
}
// cout<<value<<" i "<<i<<" index "<<index<< endl;
long num =atoi(value.c_str());
// cout<<"num is: "<<num<<endl;
if(num>255) {
return; // 直接剪除子树
}
backtrack(s,path+value+".",i+1,count+1); // 这里隐藏了递归
}
}
};
90. 子集 II
难度中等472收藏分享切换为英文接收动态反馈
给你一个整数数组 nums
,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。
示例 1:
输入:nums = [1,2,2]
输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]
示例 2:
输入:nums = [0]
输出:[[],[0]]
![](https://gitee.com/black-cat-loves-fawn/blogimage/raw/master/blogimage/20210331113343.jpeg)
used[i-1]==true说明同一枝使用过nums[i-1]
used[i-1]==false说明同一树层使用过nums[i-1]
另外还需要排序因为
代码
class Solution {
public:
vector<vector<int>> res;
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(),nums.end());
vector<int> path;
vector<bool> used(nums.size(),false);
backtrack(nums,path,0,used);
return res;
}
void backtrack(vector<int> & nums, vector<int>& path ,int index , vector<bool> used) {
res.push_back(path);
if(index>=nums.size()) {
return;
}
for(int i=index;i<nums.size();i++) {
if(i>0&& nums[i]==nums[i-1]&& used[i-1]==false) {
// cout<<i<<" "<<nums[i]<<" "<<nums[i-1]<<" " <<used[i-1]<<endl;
continue;
}
path.push_back(nums[i]);
used[i]=true;
backtrack(nums,path,i+1,used) ;
path.pop_back();
used[i]=false;
}
}
};