代码随想录算法训练营:24/60

鸿蒙进阶——HDI及IDL硬件接口IPC框架小结 HDI(Hardware Device Interface):OpenHarmony硬件设备接口,定义系统中跨进程通信的接口,实现服务间的跨进程通信 阅读详情

非科班学习算法day24 | LeetCode93:复原IP地址 ,Leetcode78:子集 ,Leetcode90: 子集||


介绍

包含LC的几道题目,还有相应概念的补充。

相关图解和更多版本:

代码随想录 (programmercarl.com)https://programmercarl.com/#%E6%9C%AC%E7%AB%99%E8%83%8C%E6%99%AF


一、LeetCode题目

1.LeetCode93:复原ip地址 

题目链接:93. 复原 IP 地址 - 力扣(LeetCode)

题目解析

       理解角度很重要,我们可以将问题化归,将其理解为划分类似的做法,不过这次要将划线(‘.’)插入到原始字符串,当然这里也可以仍然利用路径来做,不过要注意的更多了,后面仅仅贴出尝试结果。不过哪种做法都需要一个辅助函数判断字符串是否符合地址要求,就和判断是否是回文串一样,极大的帮助我们代码分块,理清楚逻辑。

 c++代码如下:

class Solution {
public:
    // 类似分割问题,不过需要插入新的字符

    // 创建结果
    vector<string> res;

    // 判断合法字符串
    bool isValid(string s, int start, int end) {
        // 不满足情况
        // 1.没有在0到255

        // 2.不能有前导0
        if (start > end)
            return false;
        if (s[start] == '0' && start != end)
            return false;
        int num = 0;
        for (int i = start; i <= end; i++) {
            if (s[i] < '0' || s[i] > '9')
                return false;
            num = num * 10 + (s[i] - '0');
            if (num > 255)
                return false;
        }
        return true;
    }
    // 回溯函数
    void backtracking(string& s, int index, int pointnum) {
        // 终止条件
        if (pointnum == 3) {
            if (isValid(s, index, s.size() - 1)) {
                res.push_back(s);
            }
            return;
        }

        for (int i = index; i < s.size(); ++i) {
            if (isValid(s, index, i)) {
                s.insert(s.begin() + i + 1, '.');
                pointnum++;
                backtracking(s, i + 2, pointnum);
                pointnum--;
                s.erase(s.begin() + i + 1);
            } else
                break;
        }
    }
    vector<string> restoreIpAddresses(string s) {
        backtracking(s, 0, 0);
        return res;
    }
};

注意点1:最重要的i+2,因为现在引用字符串已经加入了一个点。

注意点2:引入了点计数,帮助我们判断什么时候达到中止条件,中止添加结果之前需要检查第四部分是否符合我们的地址要求!

注意点3:这个辅助函数是对字符串很经典的操作,多写多练

用路径的c++代码:

class Solution {
public:
    // 创建接受结果
    vector<string> res;
    // 创建路径
    string path;

    // 创建检验IP地址部分是否合法的函数
    bool isValidPart(const string& s) {
        if (s.empty() || s.size() > 3) return false;
        if (s.front() == '0' && s.size() > 1) return false; // 0开头的多位数不合法
        int val = stoi(s);
        return val >= 0 && val <= 255;
    }

    // 创建回溯函数
    void backtracking(string s, int startIndex, int partCount) {
        if (partCount == 4) {
            if (startIndex == s.size()) {
                res.push_back(path);
            }
            return;
        }

        for (int len = 1; len <= 3 && startIndex + len <= s.size(); ++len) {
            string curPart = s.substr(startIndex, len);
            if (isValidPart(curPart)) {
                if (partCount != 0) {
                    path += ".";
                }
                path += curPart;
                backtracking(s, startIndex + len, partCount + 1);
                path.resize(path.size() - curPart.size());
                if (partCount != 0) {
                    path.pop_back(); // 移除最后一个"."
                }
            }
        }
    }

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

 2.Leetcode78:子集 

题目链接:78. 子集 - 力扣(LeetCode)

题目解析

       子集问题和组合问题最大的区别就是:组合需要全部元素,也就是说组合收集的是叶子节点,而子集问题需要的是所有的可能。

 C++代码如下: 

class Solution {
public:
    // 子集问题最重要的是收获包括中间节点
    // 结果
    vector<vector<int>> res;
    // 路径
    vector<int> path;
    // 回溯函数-还是需要index,因为要的是组合不是排列
    void backtracking(vector<int>& nums, int index) {
        // 添加结果
        res.push_back(path);
        // 中止
        for (int i = index; 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 res;
    }
};

 注意点1:这里需要没有显式的写中止条件,其实就是中止在for循环全部结束之后,所以可以省略中止条件。

注意点2:这里需要在进入递归时就将结果收集,而不是判断结果之后收集,可以借助空集来理解这个问题。

3.Leetcode90:子集||

题目链接:90. 子集 II - 力扣(LeetCode)

题目解析

       子集的进阶,多了一个条件就是数组内部存在重复的元素,这就和之前在组合遇到的去重很像,就是在树枝去重。其他的部分就和子集的算法没有区别。

C++代码如下:

class Solution {
public:
    // 和子集的区别就是有重复元素-树层去重
    // 结果
    vector<vector<int>> res;
    // 路径
    vector<int> path;

    // 回溯函数
    void backtracking(vector<int>& nums, int index, vector<bool>& used) {
        // 收集结果
        res.push_back(path);

        for (int i = index; i < nums.size(); i++) {
            // 树层去重
            if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]) {
                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) {
        // 初始化usd数组-因为要借助nums所以没有放在全局
        vector<bool> used = vector<bool>(nums.size(), false);
        sort(nums.begin(), nums.end());
        backtracking(nums, 0, used);
        return res;
    }
};

注意点1:去重一定要将数组排序!

使用set的C++代码如下:

class Solution {
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& nums, int startIndex) {
        result.push_back(path);
        unordered_set<int> uset;
        for (int i = startIndex; i < nums.size(); i++) {
            if (uset.find(nums[i]) != uset.end()) {
                continue;
            }
            uset.insert(nums[i]);
            path.push_back(nums[i]);
            backtracking(nums, i + 1);
            path.pop_back();
        }
    }

public:
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        result.clear();
        path.clear();
        sort(nums.begin(), nums.end()); // 去重需要排序
        backtracking(nums, 0);
        return result;
    }
};

注意点1:学习了一下使用set的方法,set去重的逻辑也比较直接,每一次检查在设定的set中是否有之前添加的相同元素,如果有就跳过,没有就将其加入然后执行递归。

注意点2:set的find返回的是迭代器位置!

总结


打卡第24天,坚持!!!

〖Python网络爬虫实战㊴〗- 极验滑块介绍(一) 我们对这个看到不陌生,现在,大多数平台都是用的是这个平台的验证码,我们今天来学习一下,极验滑块验证码的逆向,其他的都差不多。我们了解到这个平台提供了许多验证的方式。现在大多数还是滑块比较多,滑块验证码是一种常见的验证方式,其主要思路为用户通过拖动滑块来完成验证。具体流程如下:首先,用户需要进行滑块验证码的操作,网站会向用户展示一张图片,图片上通常会有一些随机的文字和背景干扰。用户需要通过鼠标拖动滑块,将其移动到指定位置上,通常是将滑块拖动到图片的相应位置上来完成验证。 阅读详情

相关推荐

慕课软件质量保证与测试(习题集)

慕课金陵科技学院.软件质量保证与测试.期末复习.习题汇总0 总目录1 绪论1.1 软件质量保证与测试的产生与发展1.2 软件缺陷,软件错误,软件故障1.3 软件质量保证与测试的意义,原则和挑战1.4 单元测试1.5 课后作业2 软件测试策略2.1 软件测试的模型,过程和生命周期2.2 软件测试的方法和技术2.3 单元测试2.4 课后作业3 黑盒测试3.1 黑盒测试概述3.2 等价类划分测试3.3 边界值测试3.4 错误推测法3.5 判定表驱动法3.6 因果图法3.7 场景法3.8 正交实验法3.9 单元测试

weixin_42473228的博客 5万+

网站收藏箱

文章内容都是笔者日常工作与学习接触到,并且觉得不错的网站,特收录在册,欢迎广大读者提供补充,文章会持续更新

沉梦听雨的博客 1万+

STM32 WinUSB免驱实现:从DFU模式到高速通信的实战指南

本文详细介绍了STM32 WinUSB免驱实现方案,从DFU模式到高速通信的完整实战指南。通过修改设备描述符、添加BOS描述符和实现WCID描述符集,开发者可以轻松实现即插即用的USB设备,无需额外安装驱动。文章还提供了性能优化技巧和实际应用案例,帮助开发者快速部署高效稳定的USB通信方案。

weixin_29171087的博客 422

算法速成之代码随想录

有些同学想要学习算法题,但是时间很紧,自己的基础也不是很好,想要在空余时间完全掌握所有算法题确实有点不切实际了,终于去学习了遇到难题又半途而废,于是我总结了一下刷代码随想录题目的方法先看b站视频:BV1fA4y1o715,有规划的看,每一类题可以看一到两道,看完去做题,感觉基本了解了就可以直接看代码随录博客的题目跟着做,因为看视频较为费时间,博客中的注释非常详细;写题时候,,实在无从下手就他的,看完应该都能自己写了,如果连思路都看不懂,那么就求助gpt或者去看他的视频;每周写题也要有一定的规划,

qq_63728673的博客 7033

第四章、Isaacsim在GUI中构建机器人(3):添加摄像头和传感器

本节。

m0_47719040的博客 2495

OpenFOAM-多孔介质模型(porous media)

文章目录一、多孔介质(porous media)二、使用步骤1.达西定律2.Darcy-Forchheimer3.OpenFOAM fvOptions4.paraview动画每帧显示时间(Annotate Time)5.参考内容总结 一、多孔介质(porous media) 在流体力学中,流体流经多孔介质是指流体流经多孔介质时的行为方式,如海绵或木材,或使用沙子或其他多孔材料过滤水。 我们将展示如何设置多孔层,并使用OpenFOAM模拟流体通过该介质。 二、使用步骤 1.达西定律 达西定律最初是由达西通.

zq93538196的博客 9938

代码随想录|学习工具分享

遇到看不懂的方法的时候(C++),可能是宏定义, 方法本身就是一个 宏定义,所以要找到定义他的地方,这种项目的代码 估计宏定义满天飞,如果没有好的文档,代码很难看自增自减运算符只能用于变量;不能用于常量和表达式。在使用map容器存储多个键值对时,容器会自动根据键值对的键大小,按照既定的规则进行排序(默认升序,可以自定义)使用map存储的键值对,键既不能重复也不能修改multimap和map的区别在于multimap容器可以同时存储多个键相同的键值对。

2303_79299383的博客 8703

别再纠结了!车规MCU选M7还是R52?一张图看懂你的车身控制器/域控制器该用谁

本文深入探讨车规MCU选型中Cortex-M7与Cortex-R52的核心差异,提供基于安全等级与实时性需求的选型决策图。通过对比ASIL认证、实时性能及成本效益,帮助工程师在车身控制器/域控制器设计中做出精准选择,避免潜在风险与隐性成本。

weixin_42628688的博客 397

代码随想录刷题笔记 (python版本) 持续更新.....

代码随想录刷题笔记

hello world 1万+

KEPServerEX与三菱iQ-R系列PLC通讯

KEPServerEX与三菱iQ-R系列PLC通讯Mitsubishi Ethernet北京东方鼎晨科技有限公司目 录1. 前言2. 三菱PLC端相关设置3. Kepware端相关设置KEPServerEX是美国PTC Kepware公司生产的具有行业性的连接平台,KEPServerEX支持150多种通讯协议,用于向您的所有应用程序提供单一来源的工业自动化数据。该平台的设计使用户能够通过一个直观的用户界面来连接、管理、监视和控制不同的自动化设备和软件应用程序。KEPServerEX利用OPC(自动化产业的互

qq_28768521的博客 8097

198、影像系统设计评审流程:从需求评审到 EVT、DVT、PVT 各阶段的关注重点

本文详细介绍了影像系统从需求评审到EVT、DVT、PVT各阶段的设计评审流程及关键点。作者通过实际案例(如IMX766模组偏紫问题)强调硬件工艺的重要性,指出影像系统是功能定义与物理实现的反复拉锯过程。文章分阶段解析:需求评审需将模糊需求转化为物理参数;架构评审要明确接口定义和时序约束;EVT阶段重点关注模组一致性和基础链路;DVT阶段需平衡算法调优与硬件验证;PVT阶段则以量产一致性为核心。最后提出建立"边界条件确认表"和"健康度看板"等实用建议,强调工程师需具备从表象追溯硬件根源的物理直觉。全文贯穿实战

sundong_81的博客 218

代码随想录刷题汇总

网站:https://www.programmercarl.com/

不思考会变草履虫哦 7263

华为OD机试真题 新系统2026-04-01 C++ 实现【勇攀数字高峰】

请你在给定的数字地形图中寻找登山路径,数字代表当前位置的海拔高度,要求从最低海拔出发,不断攀登,最终到达最高山峰。你需要寻找所有满足条件的登山路径。地图已经保证最低海拔和最高山峰都只有一个。

MISAYAONE的博客 383

代码随想录算法训练营完结篇 ★★★

训练营笔记完结篇。

weixin_41725662的博客 2585

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

代码随想录算法训练营第60期第四天打卡

大家好,今天刚刚参加完蓝桥杯,感觉自己要完蛋了,没几道会的题目,或许是自己的实力还不够强,或许是题目难,无论结果如何我还是继续努力把训练营布置的任务认真完成,在开始今天的题目之前我先要告诉大家一个道理,就是失败不可怕,拿不到奖更不可怕,重要的是你的精气神绝对不能丢,一定要坚持下去,那在短暂的平复心请之后,我们要开始今天的题目了,估计今天的题目对我会比较有难度,因为以前我没刷过,今天是第一次刷,那就来吧。 首先我们先来回顾一下,链表与数组是有很大的区别的,包括增删改都很不一样,同样今天的两两交换链

2401_83782806的博客 740

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

代码随想录-算法训练营day60(单调栈03:柱状图中最大的矩形)

单调栈03:数组中的最大矩形

weixin_61931006的博客 675

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

代码随想录算法训练营:4/60

包含LC的四道题目,还有相应概念的补充。

Dustin_c的博客 1076

39期代码随想录算法训练营总结

这60天正如卡哥所说前面十几天每天都能跟上,不论是在规定时间还是后面花时间补,最后都能赶上,但是到了中期,我本人是在第24天开始在回溯算法那一章节开始搁置了,因为学校进入复习周,自己就在这次训练营里懈怠了,等到了期末周结束后放暑假了,我终于开始补了,记得一开始不的章节是动态规划,由于这个章节可能相对容易理解再加上本人热情高涨,那几天的效率和积极性都很高,后面到了图论从第5天开始后就没有完整的刷过,每天也是只完成了其中一道,可能因为太难了沉不下心去学。于我而言学算法算是其中之一。

2302_78039690的博客 366

代码随想录系统性一刷总结

指针思想很重要day01 二分查找+移除元素day02 数组平方+长度最小子数组+螺旋矩阵II。

qq_44072579的博客 1048

day24 代码随想录算法训练营 回溯专题3

复原IP地址(分割问题)、子集问题、子集问题去重

I_CLK的博客 1104

代码随想录刷题60天 第1天

无

迪玛希的女朋友的博客 225

代码随想录总结篇章

历时两个月60天的代码随想录结束了,本次一刷leetcode收获很多,将经典题目都刷了一遍,感觉到自己的代码能力有显著提升,感谢老师们每天的提醒,原来想着两个月坚持下来是件难事,但坚持下来后发现也没有那么难,日积月累收获良多,下面是各题型总结:来源于同期录友:代码随想录算法训练营总结-优快云博客 来源于同期录友:代码随想录算法训练营总结-优快云博客

qq_60959261的博客 1098

算法60天:Day 4-链表中的强大快慢指针

代码随想录(截图自参考【1】) 本系列是代码随想录算法训练营的学习笔记之day4,主要记录一下刷题的过程,以及核心知识点和一些值的记录的问题。 代码随想录的资源都是免费的,具体可以看参考链接【1】。 今日知识点 链表理论基础: 链表是一种串联、线性结构;每个节点有两部分组成,值域和指针域,指针域存放指向下一个节点的指针;最后一个节点的指针域指向null(注意不同语言的写法,比如python是None); 今日题目 两两交换链表中的节点(24) 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的

qq_41387508的博客 260

二刷代码随想录——动态规划day47

一个本硕双非的小菜鸡,备战24年秋招,计划二刷完卡子哥的刷题计划,加油!

qq_43264167的博客 550

代码随想录算法训练营19期第4天

链表

u013003382的博客 141

代码随想录训练营-福工研二(日常更新进度4/60)

代码随想录,记录60天代码学习过程。 以梦为马,不负韶华!!!

qq_41346239的博客 194
上一篇: 代码随想录算法训练营:23/60
下一篇: 代码随想录算法训练营:26/60
Dustin_c
博客等级 码龄3年 391粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值