代码随想录算法训练营29期Day28|LeetCode 93,78,90

文档讲解:复原IP地址 子集 子集II

93.复原IP地址

题目链接: https://leetcode.cn/problems/restore-ip-addresses/description/

思路:

这题其实不用搜索也能做,模拟即可。

题目中已经告诉我们,ip地址是由四个0-255之间的数字构成的。因此在给出的字符串中我们只需要枚举出三个隔板,也就是排列组合中的插板法。有三个隔板就能把原字符串分割成四部分,我们以此判断每部分是否有前导0,是否位于0-255之间就可以了。这样做时间复杂度肯定不会超,算一下组合数就知道了。

核心代码:

cpp 复制代码
class Solution {
private:
    vector<string> ans;
    void dfs(string s,int p,int q,int r){
        long long x=0;
        string ss="";
        for(int i=0;i<=p;i++) x*=10,x+=s[i]-'0',ss+=s[i];
        if((s[0]=='0'&&p>0)||x<0||x>255) return;
        ss+='.';x=0;
        for(int i=p+1;i<=q;i++) x*=10,x+=s[i]-'0',ss+=s[i];
        if((s[p+1]=='0'&&q>p+1)||x<0||x>255) return;
        ss+='.';x=0;
        for(int i=q+1;i<=r;i++) x*=10,x+=s[i]-'0',ss+=s[i];
        if((s[q+1]=='0'&&r>q+1)||x<0||x>255) return;
        ss+='.';x=0;
        for(int i=r+1;i<=s.length()-1;i++) x*=10,x+=s[i]-'0',ss+=s[i];
        if((s[r+1]=='0'&&s.length()-1>r+1)||x<0||x>255) return;
        ans.push_back(ss);
    }
public:
    vector<string> restoreIpAddresses(string s) {
        int n=s.length();
        if(n<4) return ans;
        for(int i=0;i<n-3;i++)
          for(int j=i+1;j<n-2;j++)
            for(int k=j+1;k<n-1;k++)
              dfs(s,i,j,k);
        return ans;
    }
};

78.子集

题目链接: https://leetcode.cn/problems/subsets/description/

思路:

本题很简单,就是给集合求所有子集嘛。那我们枚举集合中的每个数是否在集合中就可以了。利用dfs去做,递归边界条件为集合搜索到头,这时将枚举出的在子集中的数加入答案即可。时间复杂度为O(),n<=10,所以一定能过。

核心代码:

cpp 复制代码
class Solution {
private:
    vector<vector<int>> ans;
    vector<int> num;
    void dfs(vector<int> &nums,int x){
        if(x==nums.size()){
            ans.push_back(num);
            return;
        }
        dfs(nums,x+1);
        num.push_back(nums[x]);
        dfs(nums,x+1);
        num.pop_back();
        return;
    }
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        dfs(nums,0);
        return ans;
    }
};

90.子集II

题目链接: https://leetcode.cn/problems/subsets-ii/description/

思路:

本题与LeetCode 40类似。我们可以采用类似的处理方法。

首先对原数据进行统计,统计出不同的数值以及每种数值出现的个数。

然后我们进行递归。在每层搜索中,我们枚举每种数值在子集中出现了多少个,从0依次至最大次数,然后将其在子集中加入对应次数。递归边界条件为每种数值都枚举了个数,将枚举出的子集加入答案,然后回溯即可。注意回溯时在子集中加的数要全部退掉。

核心代码:

cpp 复制代码
class Solution {
private:
    vector<pair<int,int>> tot;
    vector<vector<int>> ans;
    vector<int> num;
    void dfs(int x){
        if(x==tot.size()){
            ans.push_back(num);
            return;
        }
        for(int i=0;i<=tot[x].second;i++){
            dfs(x+1);
            num.push_back(tot[x].first);
        }
        for(int i=0;i<=tot[x].second;i++) num.pop_back();
        return;
    }
public:
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        for(int i:nums){
            if(tot.empty()||i!=tot.back().first) tot.emplace_back(i,1);
            else tot.back().second++;
        }
        dfs(0);
        return ans;
    }
};

今日总结

今日学习时长3h,题目还算可以。感冒差不多好了,状态很好,这几天要好好赶进度了。

相关推荐
程序员-King.5 小时前
day158—回溯—全排列(LeetCode-46)
算法·leetcode·深度优先·回溯·递归
优雅的潮叭5 小时前
c++ 学习笔记之 chrono库
c++·笔记·学习
星火开发设计5 小时前
C++ 数组:一维数组的定义、遍历与常见操作
java·开发语言·数据结构·c++·学习·数组·知识
月挽清风6 小时前
代码随想录第七天:
数据结构·c++·算法
小O的算法实验室6 小时前
2026年AEI SCI1区TOP,基于改进 IRRT*-D* 算法的森林火灾救援场景下直升机轨迹规划,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
小郭团队6 小时前
2_1_七段式SVPWM (经典算法)算法理论与 MATLAB 实现详解
嵌入式硬件·算法·硬件架构·arm·dsp开发
充值修改昵称7 小时前
数据结构基础:从二叉树到多叉树数据结构进阶
数据结构·python·算法
Deepoch7 小时前
Deepoc数学大模型:发动机行业的算法引擎
人工智能·算法·机器人·发动机·deepoc·发动机行业
点云SLAM7 小时前
C++内存泄漏检测之Windows 专用工具(CRT Debug、Dr.Memory)和Linux 专业工具(ASan 、heaptrack)
linux·c++·windows·asan·dr.memory·c++内存泄漏检测·c++内存管理
浅念-7 小时前
C语言小知识——指针(3)
c语言·开发语言·c++·经验分享·笔记·学习·算法