@代码随想录算法训练营第28天 | LeetCode93.复原IP地址,78.子集,90.子集II
93.复原IP地址
第一遍读题思考
问题可以翻译成在给定的字符串中插入三个“.”,所以在回溯的树结构中,每一层都是插入一个节点
代码随想录解法思路
难点在于如何perform插入这个操作,需要额外的path吗?不需要,只需要在原s上插入’.'然后再回溯就可以了。
还需要注意如何判断一段字符串是否是合法的,需要考虑字符串长度不为0时首字母为0是不对的,字母中有0-9之外的数是不对的,然后字符串所代表的整数是大于255也是不对的。
c++代码具体实现注意事项
注意字符串在特定位置插入是怎么操作的?
(递归版本)
class Solution {
public:
vector<string> result;
void traversal(string& s, int start, int pointNum){
if(pointNum==3){
if(isValid(s, start, s.size()-1)){
result.push_back(s);
}
return;
}
for(int i=start;i<s.size();i++){
if(isValid(s,start,i)){
s.insert(s.begin()+i+1, '.');
pointNum++;
traversal(s, i+2, pointNum);
pointNum--;
s.erase(s.begin()+i+1);
}
else break;
}
}
bool isValid(string s, int start, int end){
if(start>end) return false;
if(start<end && s[start]=='0'){
return false;
}
int num=0;
num = s[start]-'0';
for(int i=start+1;i<=end;i++){
if(s[i]>'9' || s[i]<0){
return false;
}
num=(num*10+(s[i]-'0'));
if(num>255) return false;
}
return true;
}
vector<string> restoreIpAddresses(string s) {
traversal(s, 0, 0);
return result;
}
};
78. 子集
第一遍读题思考
按照分割的思路来进行就涉及到要切几刀的问题,按照子集长度的思路来有涉及到几种不同的长度。
代码随想录解法思路
这道题是回溯问题中的第三类问题(前两个分别是组合问题和分割问题),这个叫做子集问题。与之前的不同是,前面的问题都是收集树的叶子节点,而子集问题是收集所有的节点.也就是按照最基本的回溯模板进行遍历,然后存储每个节点上的子集
c++代码具体实现注意事项
(递归版本)
class Solution {
public:
vector<vector<int>> result;
vector<int> subset;
void tra(vector<int> nums, int begin){
result.push_back(subset);
if(begin==nums.size()){
return;
}
for(int i=begin;i<nums.size();i++){
subset.push_back(nums[i]);
tra(nums, i+1);
subset.pop_back();
}
}
vector<vector<int>> subsets(vector<int>& nums) {
tra(nums, 0);
return result;
}
};
90.子集||
第一遍读题思考
去重操作跟40.组合总和||是一样的,同层不可取相同,排序进行比较前一项即可。
代码随想录解法思路
一样
c++代码具体实现注意事项
(递归版本)
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void tra(vector<int> nums, int start){
result.push_back(path);
if(start==nums.size()){
return;
}
for(int i=start;i<nums.size();i++){
if(i>start && nums[i]==nums[i-1]){
continue;
}
path.push_back(nums[i]);
tra(nums, i+1);
path.pop_back();
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(), nums.end());
tra(nums, 0);
return result;
}
};