day28 代码回想录 复原IP地址&子集&子集II

大纲

● 93.复原IP地址

● 78.子集

● 90.子集II

93.复原IP地址

题目:93.复原IP地址

复原ip地址,需要将字符串进行分隔,特别小心处理ip格式的判断

本题也是字符分割的题目,确定分割的点,作为递归参数传入

vector<string> ret;
vector<string> path;

// 没有考虑到不是ip,如果不是ip格式 当path > 4 或者小于3, 判断ip逻辑错误,需要加上0开头删除
// substr()参数传错误了

bool isIp(string& s, int startIndex, int endIndex)
{
    int sum = 0;
    for (int i = startIndex; i < endIndex + 1; ++i) {
        sum += (s[i] - '0') * 10 ^ (endIndex - i);
    }
//    count << "sum:" << sum << endl;
    if (sum >= 0 && sum <= 255)
        return true;
    return false;
}

bool isIp2(string& s, int startIndex, int endIndex) {
    string tmp = s.substr(startIndex, endIndex - startIndex + 1);

    // 删除0开头的
    if (tmp.size() > 1 && tmp[0] == '0')
        return false;
    int val = std::atoi(tmp.c_str());
    if (val >= 0 && val <= 255)
        return true;
    return false;
}
void _combineIp(string& s, int splitIndex)
{
    // 如果不是ip格式 当path > 4 或者path < 4也不是
    if (path.size() > 4) {
        return;
    }
    // 当所有字符都切割完了
    if (splitIndex >= s.size() && path.size() == 4) {
        // 组成ip地址
        string s;
        for (int i = 0; i < path.size(); ++i) {
            s.append(path[i]);
            if (i != path.size() - 1)
                s.append(".");
        }
        ret.push_back(s);
        return;
    }
    // 切割剩下的字符 [splitIndex, i]
    for (int i = splitIndex; i < s.size(); ++i) {
        if (!isIp(s, splitIndex, i)) {
            continue;
        }
        string sub = s.substr(splitIndex, s.size() - i + 1);
        path.push_back(sub);
        _combineIp(s, i + 1);
        path.pop_back();
    }
}
vector<string> getCombineIp(string& s) {
    _combineIp(s, 0);
    return ret;
}

78.子集

题目:78.子集

返回集合中元素可以组成的集合

// 求子集
// 思路从第一个元素开始遍历
// 结束条件:抵达最后一个元素
// 单层循环:[startIndex,i]区间取值并加入结果集合
// 错误在于最后一个元素会重复选,且没有[]包含

// 没有path保存回溯了 不知道是不是这个问题导致的错误
vector<vector<int>> ret1;
vector<int> path1;
void _subArr(vector<int>& nums, int startIndex)
{
    // 添加
    ret1.push_back(path1);
    if (startIndex >= nums.size()) {
        return;
    }
    for (int i = startIndex; i < nums.size(); ++i) {
//        vector<int> tmp(nums.begin() + startIndex, nums.begin() + i + 1);
//        ret1.push_back(tmp);
        path1.push_back(nums[i]);
        _subArr(nums, i + 1);
        path1.pop_back();
    }
}

vector<vector<int>> subArray(vector<int>& nums) {
    _subArr(nums, 0);
    return ret1;
}

90.子集II

题目:90.子集II

本题和上一题的区别是集合中的元素会重复,需要处理重复的子集

// 求子集2
// 如果nums集合里面有重复元素
// 要求返回不重合的子集
// 排序,过滤掉相邻重复的元素
void _subArray2(vector<int> & nums, int sliderIndex) {
    ret1.push_back(path1);
    if (sliderIndex >= nums.size()) return;

    for (int i = sliderIndex; i < nums.size(); ++i) {
        // 过滤重复元素
        if (i > sliderIndex && nums[i - 1] == nums[i])
            continue;
        path1.push_back(nums[i]);
        _subArray2(nums, i + 1);
        path1.pop_back();
    }
}

vector<vector<int>> subArray2(vector<int>& nums) {
    sort(nums.begin(), nums.end());
    _subArray2(nums, 0);
    return ret1;
}
相关推荐
daily_23333 分钟前
数据结构——小小二叉树第三幕(链式结构的小拓展,二叉树的创建,深入理解二叉树的遍历)超详细!!!
数据结构·c++·算法
浦东新村轱天乐25 分钟前
神经网络反向传播算法公式推导
神经网络·算法·机器学习
laimaxgg27 分钟前
C++特殊类设计(不能被拷贝的类、只能在堆上创建对象的类、不能被继承的类、单例模式)
c++·单例模式
SUN_Gyq36 分钟前
什么是 C++ 中的模板特化和偏特化? 如何进行模板特化和偏特化?
开发语言·c++·算法
码上一元40 分钟前
【百日算法计划】:每日一题,见证成长(026)
算法
愿天垂怜1 小时前
【C++】C++11引入的新特性(1)
java·c语言·数据结构·c++·算法·rust·哈希算法
淡写青春2091 小时前
计算机基础---进程间通信和线程间通信的方式
java·开发语言·数据结构
大帅哥_1 小时前
访问限定符
c语言·c++
kitesxian1 小时前
Leetcode200. 岛屿数量(HOT100)
算法·深度优先
特种加菲猫1 小时前
初阶数据结构之栈的实现
开发语言·数据结构·笔记