代码随想录算法训练营第二十八天| LeetCode 93. 复原IP地址、78.子集、90.子集II

一、LeetCode 93. 复原IP地址

状态:已解决

1.思路 

        分割字符串做出来了,那么这道题也就很容易想出来,二者本质差不多,都是在进行分割。只是,对分割出的子串的有效性判断不一致了。93题判断一个子串是否有效是根据该字符串转成的int数据是否介于[0,255],以及是否有前缀0来判断的;39题则是判断是否是回文串。另外,这道题对分割出的子串数量有限制,必须为4。因此,直接根据以上变动在39题的代码上得到93题的代码。

2.完整代码

class Solution {
public:
    vector<string> path;
    vector<string> result;
    bool isValid(string& s,int startIndex,int i){
        string substrs = s.substr(startIndex,i-startIndex+1);
        if(substrs[0]=='0' && substrs.size()>1) return false;
        int value = atoi(substrs.c_str());
        if(!(0<=value && value<=255)){
            return false;
        }
        return true;
    }
    void backtracking(string& s,int startIndex,int k){
        if(startIndex >= s.size()){
            if(k==4){
                string temp="";
                for(int i=0;i<path.size();i++){
                    temp += path[i];
                    temp += ".";
                }
                temp.pop_back();
                result.push_back(temp);
            }
            return ;
        }
        for(int i=startIndex;i<s.size();i++){
            if(isValid(s,startIndex,i)){
                string substrs = s.substr(startIndex,i-startIndex+1);
                path.push_back(substrs);
                backtracking(s,i+1,k+1);
                path.pop_back();
            }
            else{
                continue;
            }
        }
        return;
    }
    vector<string> restoreIpAddresses(string s) {
        backtracking(s,0,0);
        return result;
    }
};

二、78.子集

题目链接/文章讲解/视频讲解: https://programmercarl.com/0078.%E5%AD%90%E9%9B%86.html
状态:已解决

1.思路 

        这题也就是回溯法的模板题的简单升级,只比模板题多了一点变动。模板题是每次在叶子节点处存数据,而此题在树层处就要存数据,即每条枝干上的每个节点都要存。也就是说,result.push_back(path)要放到终止条件的外部。

2.完整代码 

class Solution {
public:
    vector<int> path;
    vector<vector<int>> result;
    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) {
        backtracking(nums,0);
        return result;
    }
};

三、90.子集II

题目链接/文章讲解/视频讲解: https://programmercarl.com/0090.%E5%AD%90%E9%9B%86II.html
状态:已解决

1.思路 

        这和40题差不多,由于有重复元素,故此题与40题一样都需要去重。区别在于40题存路径的条件是要满足路径各节点值之和等于target,此题没有这个限制,故每个中间路径都要存,这又与78题类似,因此这题实则是78题和40题的结合:40题的去重思路(树枝去重used数组、树层去重nums[i]==nums[i-1])、78题的存路径思路(每条中间路径都要存)。

2.代码实现

class Solution {
public:
    vector<int> path;
    vector<vector<int>> result;
    void backtracking(vector<int>& nums,int startIndex,vector<int> used){
        result.push_back(path);//78题找子集,在于每个中间路径都要存
        if(startIndex>=nums.size()){
            return ;
        }
        for(int i=startIndex;i<nums.size();i++){
            if(i>0 && nums[i]==nums[i-1] && used[i-1]==0){
                continue;
            }//40题去重做法,双重去重。
            path.push_back(nums[i]);
            used[i]=1;
            backtracking(nums,i+1,used);
            used[i]=0;
            path.pop_back();
        }
    }
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        path.clear();
        result.clear();
        vector<int> used(nums.size(),0);
        backtracking(nums,0,used);
        return result;
    }
};

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值