首页 > 其他分享 >(27/60)复原IP地址、子集、子集Ⅱ

(27/60)复原IP地址、子集、子集Ⅱ

时间:2024-02-25 20:55:19浏览次数:37  
标签:begin 27 nums int 60 vector 子集 result path

阶段性还完了旧账

复原IP地址

leetcode:93. 复原 IP 地址

回溯法

思路

和分割回文串类似,只是回文串检测改为IP合法检测。

终止条件也值得注意:

复杂度分析

时间复杂度:

空间复杂度:

注意点

代码实现

递归不一定要返回!!

class Solution {
private:
    vector<string> result;
    vector<string> path;
public:
    void backtracking(string& s,int begin){
        // 分成四份的时候就及时处理,符合的就直接加入,若不符合就返回
        if(path.size() == 4){
            // begin == s.size()表示遍历完,可以放入结果集
            if(begin == s.size()){
                string str;
                for(int i = 0;i < path.size() - 1;i++){
                    str += path[i]; str += '.';
                }
                str += path[path.size() - 1];
                result.push_back(str);
            }
            
            return;
        }

        for(int i = begin;i < s.size();i++){
            if(i - begin + 1 > 3) return;   // 剪枝,如果剩余子串长度超过3就退出
            if(isValid(s,begin,i)){ // 如果字串合法,则放入path数组
                path.push_back(s.substr(begin,i - begin + 1));
                backtracking(s,i + 1);
                path.pop_back();
            }
        }
    }

    // 左闭右闭
    bool isValid(string& s, int begin, int end) {
        // 长度大于1且开头为0,去掉. 排除0开头的多位数
        if (end - begin + 1 > 1 && s[begin] == '0') return false; 
        int sum = 0;
        for (int i = begin; i <= end; i++) {
            sum = sum * 10 + (s[i] - '0');
            if (sum > 255) return false;
        }
        return true;
    }

    vector<string> restoreIpAddresses(string s) {
        backtracking(s,0);
        return result;
    }
};

子集

leetcode:78. 子集

回溯法

思路

和组合一样,不过树的每个节点都是解,都放入结果集。

复杂度分析

时间复杂度:O(2N*N)。遍历所有的结果是O(2N),将path复制进result的时间是O(N)(子集平均长度2/N)。

空间复杂度:O(N)。

注意点

  1. 空集也是所有子集里的一个。(我这里其实没有想到,阴差阳错地刚好满足了)
  2. 我这里才意识到:递归不一定要有return的,只要不是无限循环,执行完了自动会返回上一层。

代码实现

class Solution {
private:
    vector<int> path;
    vector<vector<int>> result;
public:
    // 类组合,树上每个节点都是解。
    void backtracking(vector<int>& nums,int begin){
        result.push_back(path);

        for(int i = begin;i < nums.size();i++){	// for暗含终止条件
            path.push_back(nums[i]);
            backtracking(nums,i + 1);
            path.pop_back();
        }
    }

    vector<vector<int>> subsets(vector<int>& nums) {
        backtracking(nums,0);
        return result;
    }
};

子集Ⅱ

leetcode:90. 子集 II

回溯法

思路

依旧是组合,放入每个节点,不过要去重。

先排序,然后进行树层去重(同一层,值一样的元素跳过)

复杂度分析

时间复杂度:O(2^N*N)。虽有去重,但数量级没变。

空间复杂度:

注意点

  1. 树层去重时的条件是i > begin而不是i > 0。因为要控制在同层子集范围内比较(begin~i),否则就不是同父节点的同一层了。

代码实现

使用begin下标版:

class Solution {
private:
    vector<int> path;
    vector<vector<int>> result; 
public:
    // 组合,放入每个节点,并且要去重
    // 先排序,然后进行树层去重(同一层,值一样的元素跳过)
    void backtracking(vector<int>& nums,int begin){
        result.push_back(path);

        for(int i = begin;i < nums.size();i++){
            // i > begin是因为要控制在同层子集范围内比较,否则就不是同父节点的同一层了。
            if(i > begin && nums[i - 1] == nums[i]) continue; // 同层同值元素跳过
            path.push_back(nums[i]);
            backtracking(nums,i + 1);
            path.pop_back();
        }
    }
    
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        backtracking(nums,0);
        return result;
    }
};

使用used数组版:

    class Solution {
    private:
        vector<int> path;
        vector<vector<int>> result;
    public:
        // 组合,放入每个节点,并且要去重
        // 先排序,然后进行树层去重(同一层,值一样的元素跳过)
        void backtracking(vector<int>& nums,int begin,vector<bool> used){
            result.push_back(path);

            for(int i = begin;i < nums.size();i++){
                if(i > 0 && nums[i - 1] == nums[i] && used[i-1] == false) continue; // 同层同值元素跳过
                path.push_back(nums[i]);
                used[i] = true;
                backtracking(nums,i + 1,used);
                path.pop_back();
                used[i] = false;
            }
        }
        
        vector<vector<int>> subsetsWithDup(vector<int>& nums) {
            sort(nums.begin(),nums.end());
            vector<bool> used(nums.size(),false); 
            backtracking(nums,0,used);
            return result;
        }
    };

标签:begin,27,nums,int,60,vector,子集,result,path
From: https://www.cnblogs.com/tazdingo/p/18033030

相关文章

  • 高颜值小板!华硕ROG STRIX B760-G GAMING WIFI S小吹雪评测:稳上8000!
    一、前言:连细节都尽善尽美的高颜值小吹雪主板在一众B760主板中,华硕的B760小吹雪在颜值、性能和做工方面做到了很好的平衡,很多想要打造白色小型主机的玩家都会首选这块主板。现在,升级版的ROGSTRIXB760-GGAMINGWIFIS小吹雪来了。ROGSTRIXB760-GGAMINGWIFIS小吹雪主板......
  • (26/60)组合总和、组合总和Ⅱ、分割回文串
    组合总和leetcode:39.组合总和回溯法思路在组合的基础上,只不过同一个数字可以重复选取,递归时传入i即可(组合是传入i+1)。复杂度分析时间复杂度:在最坏情况下,回溯算法会遍历所有可能的组合,因此时间复杂度取决于解的个数。假设候选数组的长度为n,目标值为target,最坏情况下解的......
  • 代码随想录算法训练营第二十七天| 93.复原IP地址 78.子集 90.子集II
    复原IP地址 题目链接:93.复原IP地址-力扣(LeetCode)思路:投降。在判断字符串是否合法这部分遇到了困难。classSolution{private:vector<string>result;//记录结果//startIndex:搜索的起始位置,pointNum:添加逗点的数量voidbacktracking(string&s,int......
  • 代码随想录 day60 回文子串 最长回文子序列
    回文子串dp[i][j]:[i,j]范围内为回文子串递推式分三种情况①:ij相等显然是回文②:j-i<1且s[i]==s[j]显然是回文③:j-i>1且dp[i+1][j-1]为true也就是当前两端元素相同看元素内部是否是回文如果是显然是ij范围内是回文初始化必须初始化falset......
  • 27.6k star,推荐一款开源的网页性能分析工具
    27.6kstar,推荐一款开源的网页性能分析工具原创 大侠之运维 大侠之运维 2024-02-2407:03 上海 听全文点击上方蓝字  关注大侠之运维大家好,这里是大侠之运维,文末有彩蛋。Lighthouse:一款优秀的网页性能分析工具Lighthouse是一款由GoogleChrome团队开发的......
  • 代码随想录算法训练营第二十七天 | 90.子集II , 78.子集, 93.复原IP地址
    93.复原IP地址 已解答中等 相关标签相关企业 有效IP地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。例如:"0.1.2.201" 和"192.168.1.1" 是 有效 IP地址,但是 "0.011.255.245"、"1......
  • 1.27
    在注册一个组件的时候,我们始终需要给它一个名字。定义组件名的方式有两种:使用kebab-case当使用kebab-case(短横线分隔命名)定义一个组件时,你也必须在引用这个自定义元素时使用kebab-case,例如<my-component-name>。使用PascalCase当使用PascalCase(首字母大写命名)定......
  • 恢复VCPkg(2023-01-27)中Vtk[Qt]的默认依赖为Qt5
    通过查看vtk的更新的日志已于2023-01-27将默认依赖的Qt的版本由5更新到6gitlog--.\ports\vtkcommit27fb19bdcc1f6ddb1261cffb5372724ac1d63a93Author:LilyWang<[email protected]>Date:2023-08-23[manyports]FixURLSofdownlo......
  • pytest简易教程(27):pytest常用插件 - 失败重试(pytest-rerunfailures)
     pytest简易教程汇总,详见:https://www.cnblogs.com/uncleyong/p/17982846关于插件pytest有很多第三方插件:https://docs.pytest.org/en/latest/reference/plugin_list.html#plugin-list总共1300多个,一般最近1年内有更新的都是常用的。 使用场景针对运行不通过的用例运行重......
  • (25/60)组合总和Ⅲ、电话号码的字母组合
    组合总和Ⅲleetcode:216.组合总和III回溯法思路组合的基础上,在找组合的过程中,把和为N的记录下来。复杂度分析时间复杂度:O(C(K,9))。空间复杂度:空间复杂度主要来自递归调用时维护的栈空间和存储结果的二维数组,分别为O(k)和O(C(K,9)*K)。注意点略代码实现classSolut......