文章链接: 93.复原IP地址、 78.子集、 90.子集II 视频链接: 93.复原IP地址、 78.子集、 90.子集II 题目链接: 93.复原IP地址、 78.子集、 90.子集II 93.复原IP地址 思路: 切割问题 1.深度(递归函数):移动startIndex 2.宽度(for循环):移动 i 登录后复制 class Solution { public: vector<string> result; void backtracking(string& s, int startIndex, int pointNum) { if(pointNum == 3) { // 判断第四段子字符串是否合法,如果合法就放进result中 if(isValid(s, startIndex, s.size() - 1)) { result.push_back(s); } return; } for(int i = startIndex; i < s.size(); i++) { if(isValid(s, startIndex, i)) { s.insert(s.begin() + i + 1, '.'); pointNum++; backtracking(s, i + 2, pointNum); s.erase(s.begin() + i + 1); pointNum--; } else { break; // [startIndex, i] 这个区间的字串不合法,直接跳出 } } } // 判断是否是有效数字 bool isValid(const string& s, int start, int end) { if(start > end) { // 第一种无效情况 return false; } if(s[start] == '0' && start != end) { // 第二种无效情况:0开头的数字无效 return false; } int num = 0; for(int i = start; i <= end; i++) { // 第三种无效情况:有非正整数字符 if(s[i] > '9' || s[i] < '0') { return false; } num = num * 10 + (s[i] - '0'); if(num > 255) { // 第四种无效情况:数字大于255 return false; } } return true; } vector<string> restoreIpAddresses(string s) { result.clear(); if(s.size() < 4 || s.size() > 12) { return result; } backtracking(s, 0, 0); return result; } }; 1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.53.54.55. 78.子集 思路: 子集问题 与组合问题、分割问题的区别:如果把 子集问题、组合问题、分割问题都抽象为一棵树的话,那么组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点! 登录后复制 class Solution { public: vector<vector<int>> result; vector<int> path; void backtracking(vector<int>& nums, int startIndex) { result.push_back(path); if(startIndex >= nums.size()) { return; } for(int i = startIndex; i < nums.size(); i++) { path.push_back(nums[i]); backtracking(nums, i + 1); path.pop_back(); } } vector<vector<int>> subsets(vector<int>& nums) { result.clear(); path.clear(); backtracking(nums, 0); return result; } }; 1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24. 90.子集II 思路: 与上题的区别:所给数组有重复元素,所以要增加去重的部分。 登录后复制 class Solution { private: vector<vector<int>> result; vector<int> path; void backtracking(vector<int>& nums, int startIndex) { result.push_back(path); for (int i = startIndex; i < nums.size(); i++) { // 对使用过的元素进行跳过(去重) if (i > startIndex && nums[i] == nums[i - 1] ) { // 注意要i > startIndex continue; } path.push_back(nums[i]); backtracking(nums, i + 1); path.pop_back(); } } public: vector<vector<int>> subsetsWithDup(vector<int>& nums) { result.clear(); path.clear(); sort(nums.begin(), nums.end()); // 去重需要排序!!!!! backtracking(nums, 0); return result; } }; 1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27. 原创作者: u_16292245 转载于: https://blog.51cto.com/u_16292245/11632663