大纲
● 93.复原IP地址
● 78.子集
● 90.子集II
93.复原IP地址
题目:93.复原IP地址
复原ip地址,需要将字符串进行分隔,特别小心处理ip格式的判断
本题也是字符分割的题目,确定分割的点,作为递归参数传入
vector<string> ret;
vector<string> path;// 没有考虑到不是ip,如果不是ip格式 当path > 4 或者小于3, 判断ip逻辑错误,需要加上0开头删除
// substr()参数传错误了bool isIp(string& s, int startIndex, int endIndex)
{int sum = 0;for (int i = startIndex; i < endIndex + 1; ++i) {sum += (s[i] - '0') * 10 ^ (endIndex - i);}
// count << "sum:" << sum << endl;if (sum >= 0 && sum <= 255)return true;return false;
}bool isIp2(string& s, int startIndex, int endIndex) {string tmp = s.substr(startIndex, endIndex - startIndex + 1);// 删除0开头的if (tmp.size() > 1 && tmp[0] == '0')return false;int val = std::atoi(tmp.c_str());if (val >= 0 && val <= 255)return true;return false;
}
void _combineIp(string& s, int splitIndex)
{// 如果不是ip格式 当path > 4 或者path < 4也不是if (path.size() > 4) {return;}// 当所有字符都切割完了if (splitIndex >= s.size() && path.size() == 4) {// 组成ip地址string s;for (int i = 0; i < path.size(); ++i) {s.append(path[i]);if (i != path.size() - 1)s.append(".");}ret.push_back(s);return;}// 切割剩下的字符 [splitIndex, i]for (int i = splitIndex; i < s.size(); ++i) {if (!isIp(s, splitIndex, i)) {continue;}string sub = s.substr(splitIndex, s.size() - i + 1);path.push_back(sub);_combineIp(s, i + 1);path.pop_back();}
}
vector<string> getCombineIp(string& s) {_combineIp(s, 0);return ret;
}
78.子集
题目:78.子集
返回集合中元素可以组成的集合
// 求子集
// 思路从第一个元素开始遍历
// 结束条件:抵达最后一个元素
// 单层循环:[startIndex,i]区间取值并加入结果集合
// 错误在于最后一个元素会重复选,且没有[]包含// 没有path保存回溯了 不知道是不是这个问题导致的错误
vector<vector<int>> ret1;
vector<int> path1;
void _subArr(vector<int>& nums, int startIndex)
{// 添加ret1.push_back(path1);if (startIndex >= nums.size()) {return;}for (int i = startIndex; i < nums.size(); ++i) {
// vector<int> tmp(nums.begin() + startIndex, nums.begin() + i + 1);
// ret1.push_back(tmp);path1.push_back(nums[i]);_subArr(nums, i + 1);path1.pop_back();}
}vector<vector<int>> subArray(vector<int>& nums) {_subArr(nums, 0);return ret1;
}
90.子集II
题目:90.子集II
本题和上一题的区别是集合中的元素会重复,需要处理重复的子集
// 求子集2
// 如果nums集合里面有重复元素
// 要求返回不重合的子集
// 排序,过滤掉相邻重复的元素
void _subArray2(vector<int> & nums, int sliderIndex) {ret1.push_back(path1);if (sliderIndex >= nums.size()) return;for (int i = sliderIndex; i < nums.size(); ++i) {// 过滤重复元素if (i > sliderIndex && nums[i - 1] == nums[i])continue;path1.push_back(nums[i]);_subArray2(nums, i + 1);path1.pop_back();}
}vector<vector<int>> subArray2(vector<int>& nums) {sort(nums.begin(), nums.end());_subArray2(nums, 0);return ret1;
}