• 代码随想录算法训练营第23期day27|93.复原IP地址、78.子集、90.子集II


    目录

    一、(leetcode 93)复原IP地址

    二、(leetcode 78)子集

    三、(leetcode 90)子集II


    一、(leetcode 93)复原IP地址

    力扣题目链接

     状态:没有写出来,待回顾

    先切割,再判断是否合法

    1. for (int i = startIndex; i < s.size(); i++) {
    2. if (isValid(s, startIndex, i)) { // 判断 [startIndex,i] 这个区间的子串是否合法
    3. s.insert(s.begin() + i + 1 , '.'); // 在i的后面插入一个逗点
    4. pointNum++;
    5. backtracking(s, i + 2, pointNum); // 插入逗点之后下一个子串的起始位置为i+2
    6. pointNum--; // 回溯
    7. s.erase(s.begin() + i + 1); // 回溯删掉逗点
    8. } else break; // 不合法,直接结束本层循环
    9. }

    判断是否合法,主要注意以下三点

    • 段位以0为开头的数字不合法
    • 段位里有非正整数字符不合法
    • 段位如果大于255了不合法
    1. // 判断字符串s在左闭又闭区间[start, end]所组成的数字是否合法
    2. bool isValid(const string& s, int start, int end) {
    3. if (start > end) {
    4. return false;
    5. }
    6. if (s[start] == '0' && start != end) { // 0开头的数字不合法
    7. return false;
    8. }
    9. int num = 0;
    10. for (int i = start; i <= end; i++) {
    11. if (s[i] > '9' || s[i] < '0') { // 遇到非数字字符不合法
    12. return false;
    13. }
    14. num = num * 10 + (s[i] - '0');
    15. if (num > 255) { // 如果大于255了不合法
    16. return false;
    17. }
    18. }
    19. return true;
    20. }

    完整代码

    1. class Solution {
    2. private:
    3. vector result;// 记录结果
    4. // startIndex: 搜索的起始位置,pointNum:添加逗点的数量
    5. void backtracking(string& s, int startIndex, int pointNum) {
    6. if (pointNum == 3) { // 逗点数量为3时,分隔结束
    7. // 判断第四段子字符串是否合法,如果合法就放进result中
    8. if (isValid(s, startIndex, s.size() - 1)) {
    9. result.push_back(s);
    10. }
    11. return;
    12. }
    13. for (int i = startIndex; i < s.size(); i++) {
    14. if (isValid(s, startIndex, i)) { // 判断 [startIndex,i] 这个区间的子串是否合法
    15. s.insert(s.begin() + i + 1 , '.'); // 在i的后面插入一个逗点
    16. pointNum++;
    17. backtracking(s, i + 2, pointNum); // 插入逗点之后下一个子串的起始位置为i+2
    18. pointNum--; // 回溯
    19. s.erase(s.begin() + i + 1); // 回溯删掉逗点
    20. } else break; // 不合法,直接结束本层循环
    21. }
    22. }
    23. // 判断字符串s在左闭又闭区间[start, end]所组成的数字是否合法
    24. bool isValid(const string& s, int start, int end) {
    25. if (start > end) {
    26. return false;
    27. }
    28. if (s[start] == '0' && start != end) { // 0开头的数字不合法
    29. return false;
    30. }
    31. int num = 0;
    32. for (int i = start; i <= end; i++) {
    33. if (s[i] > '9' || s[i] < '0') { // 遇到非数字字符不合法
    34. return false;
    35. }
    36. num = num * 10 + (s[i] - '0');
    37. if (num > 255) { // 如果大于255了不合法
    38. return false;
    39. }
    40. }
    41. return true;
    42. }
    43. public:
    44. vector restoreIpAddresses(string s) {
    45. result.clear();
    46. if (s.size() < 4 || s.size() > 12) return result; // 算是剪枝了
    47. backtracking(s, 0, 0);
    48. return result;
    49. }
    50. };

    二、(leetcode 78)子集

    力扣题目链接

    状态:已AC,就是要注意收集子集,要放在终止添加的上面

    1. class Solution {
    2. private:
    3. vectorint>> result;
    4. vector<int> path;
    5. void backtracking(vector<int>& nums, int startIndex) {
    6. result.push_back(path); // 收集子集,要放在终止添加的上面,否则会漏掉自己
    7. if (startIndex >= nums.size()) { // 终止条件可以不加
    8. return;
    9. }
    10. for (int i = startIndex; i < nums.size(); i++) {
    11. path.push_back(nums[i]);
    12. backtracking(nums, i + 1);
    13. path.pop_back();
    14. }
    15. }
    16. public:
    17. vectorint>> subsets(vector<int>& nums) {
    18. result.clear();
    19. path.clear();
    20. backtracking(nums, 0);
    21. return result;
    22. }
    23. };

    三、(leetcode 90)子集II

    力扣题目链接

     状态:修改后AC

    1. class Solution {
    2. private:
    3. vectorint>> result;
    4. vector<int> path;
    5. void backtracking(vector<int>& nums, int startIndex, vector<bool>& used) {
    6. result.push_back(path);
    7. for (int i = startIndex; i < nums.size(); i++) {
    8. // used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
    9. // used[i - 1] == false,说明同一树层candidates[i - 1]使用过
    10. // 而我们要对同一树层使用过的元素进行跳过
    11. if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {
    12. continue;
    13. }
    14. path.push_back(nums[i]);
    15. used[i] = true;
    16. backtracking(nums, i + 1, used);
    17. used[i] = false;
    18. path.pop_back();
    19. }
    20. }
    21. public:
    22. vectorint>> subsetsWithDup(vector<int>& nums) {
    23. result.clear();
    24. path.clear();
    25. vector<bool> used(nums.size(), false);
    26. sort(nums.begin(), nums.end()); // 去重需要排序
    27. backtracking(nums, 0, used);
    28. return result;
    29. }
    30. };

     

     

     

     

     

  • 相关阅读:
    k8s基础命令及Linux上用Kubectl(k8s)部署Nginx
    微软如何打造数字零售力航母系列科普02 --- 微软低代码应用平台加速企业创新 - 解放企业数字零售力
    C++知识点梳理:包装类型/词汇类型 vocabulary types
    Vue的自定义事件(Custom Events):实现组件间通信的强大工具
    【Vue】VueX 的语法详解(3)
    力扣(309.714)补8.5
    C++中类和动态内存分配
    模块化开发_groupby查询think PHP5.1
    人家不卡学历,是自己真的没能力
    八:ffmpeg命令提取像素格式和PCM数据
  • 原文地址:https://blog.csdn.net/weixin_42179093/article/details/133953174