【代码随想录】【算法训练营】【第28天】 [93]复原IP地址 [78]子集 [90]子集II

news2024/11/16 17:52:36

前言

思路及算法思维,指路 代码随想录。
题目来自 LeetCode。

day 28,工作的周二~

题目详情

[93] 复原 IP 地址

题目描述

93 复原 IP 地址
93 复原 IP 地址

解题思路

前提:分割问题
思路:回溯算法,确定每次递归回溯的分割位置。
重点:主要考虑清除分割位置的选取,即树状结构的划分。

代码实现

C语言
回溯

保存.的位置 + 字符串尾\0 + returnSize初始化为0

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */

bool isValidIp(char *s, int startIdx, int endIdx)
{
    if ((s == NULL) || (strlen(s) == 0) || (startIdx > endIdx))
    {
        return false;
    }
    // 起始为0情况
    if ((s[startIdx] == '0') && (startIdx != endIdx))
    {
        return false;
    }
    // 无效字符情况
    int num = 0;
    for (int idx = startIdx; idx <= endIdx; idx++)
    {
        if ((s[idx] < '0') || (s[idx] > '9'))
        {
            return false;
        }
        num = num * 10 + (s[idx] - '0');
    }
    // 超过255情况
    if (num > 255)
    {
        return false;
    }
    return true;
}

void backtracking(char *s, int strLen, int startIdx, int protNum, int *portLoc, char ***ans, int *returnSize)
{
    // 退出条件
    if (protNum == 3) {
        // 判断最后一段是否符合IP有效段
        if (((strLen - startIdx) < 4) && (isValidIp(s, startIdx, strLen - 1))) {
            // 保存输出结果
            *ans = (char **)realloc(*ans, sizeof(char *) * (*returnSize + 1));
            (*ans)[*returnSize] = (char *)malloc(sizeof(char) * 17);
            int count = 0;
            int tmp = 0;
            for (int i = 0; i < strLen; i++)
            {
                if ((count < 3) && (portLoc[count] == i))
                {
                    (*ans)[*returnSize][tmp++] = '.';
                    count++;
                }
                (*ans)[*returnSize][tmp++] = s[i];
            }
            (*ans)[*returnSize][tmp] = '\0';
            (*returnSize)++;
        }
        return ;
    }
    //递归
    for (int idx = startIdx; (idx < strLen) && (idx < startIdx + 4); idx++)
    {
        // 判断是否为IP有效段
        if (isValidIp(s, startIdx, idx)) {
            // 有效,保存该.位置
            portLoc[protNum] = idx + 1;
        }
        else {
            continue;
        }
        backtracking(s, strLen, idx + 1, protNum + 1, portLoc, ans, returnSize);
        // 回溯
    }
}

char** restoreIpAddresses(char* s, int* returnSize) {
    *returnSize = 0;
    char **ans = NULL;
    if ((s == NULL) || (strlen(s) == 0))
    {
        return NULL;
    }
    // 输出变量初始化
    int strLen = strlen(s);
    int portLoc[3] = {0};
    backtracking(s, strLen, 0, 0, portLoc, &ans, returnSize);
    return ans;
}

[78] 子集

题目描述

78 子集
78 子集

解题思路

前提:组合子集问题, 无重复元素
思路:回溯,输出树上所有节点的路径
重点:先输出路径,再判断退出条件,以免遗漏子集。

代码实现

C语言
回溯

树的所有结点路径 + 全局变量初始化

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */

int **ans;
int ansSize = 0;
int *colSizes;
int *tmpNums;
int tmpNumsSize = 0;

void collect()
{
    ans[ansSize] = (int *)malloc(sizeof(int) * tmpNumsSize);
    for (int i = 0; i < tmpNumsSize; i++) {
        ans[ansSize][i] = tmpNums[i];
    }
    colSizes[ansSize] = tmpNumsSize;
    ansSize++;
    return ;
}

void backtracking(int *nums, int numsSize, int startIdx)
{
    // 收集该结点路径
    collect();
    // 终止条件
    if (startIdx >= numsSize) {
        return ;
    }
    // 递归
    for (int j = startIdx; j < numsSize; j++) {
        // 保存该结点
        tmpNums[tmpNumsSize++] = nums[j];
        backtracking(nums, numsSize, j + 1);
        // 回溯
        tmpNumsSize--;
    }
    return ;
}

int** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {
    // 全局变量初始化
    ans = (int **)malloc(sizeof(int *) * 10000);
    colSizes = (int *)malloc(sizeof(int) * 10000);
    tmpNums = (int *)malloc(sizeof(int) * numsSize);
    ansSize = 0;
    tmpNumsSize = 0;
    backtracking(nums, numsSize, 0);
    *returnSize = ansSize;
    *returnColumnSizes = colSizes;
    return ans;
}

[90] 子集II

题目描述

90 子集II
90 子集II

解题思路

前提:组合子集问题,有重复元素
思路:回溯,排序后同一树层去重, 输出树上所有节点的路径。
重点:同一树层去重; 先输出路径,再判断退出条件,以免遗漏子集。

代码实现

C语言
回溯

回溯 + 同一树层元素去重 + 输出全结点路径

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */

int **ans;
int ansSize;
int *length;
int *path;
int pathSize;
bool *used;

int cmp(void *p1, void *p2)
{
    return *(int *)p1 > *(int *)p2;
}

void collect()
{
    ans[ansSize] = (int *)malloc(sizeof(int) * pathSize);
    // 输出该子集
    for (int j = 0; j < pathSize; j++) {
        ans[ansSize][j] = path[j];
    }
    length[ansSize] = pathSize;
    ansSize++;
    return ;
}

void backtracking(int *nums, int numsSize, int startIndex)
{
    // 输出该子集
    collect();
    // 退出条件
    if (startIndex >= numsSize) {
        return;
    }
    // 递归
    for (int i = startIndex; i < numsSize; i++) {
        // 去重
        if ((i > 0) && (nums[i] == nums[i - 1]) && (used[i - 1] == false)) {
            continue;
        }
        // 保存该元素
        path[pathSize++] = nums[i];
        used[i] = true;
        backtracking(nums, numsSize, i + 1);
        // 回溯
        pathSize--;
        used[i] = false;
    }
    return ;
}

int** subsetsWithDup(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {
    // 全局变量初始化
    ans = (int **)malloc(sizeof(int *) * 10000);
    ansSize = 0;
    length = (int *)malloc(sizeof(int) * 10000);
    path = (int *)malloc(sizeof(int) * numsSize);
    pathSize = 0;
    used = (bool *)malloc(sizeof(bool) * numsSize);
    for (int k = 0; k < numsSize; k++) {
        used[k] = false;
    }

    // 排序
    qsort(nums, numsSize, sizeof(int), cmp);

    // 回溯
    backtracking(nums, numsSize, 0);

    // 赋值输出结果
    *returnSize = ansSize;
    *returnColumnSizes = length;

    return ans;
}

今日收获

  1. 组合分割问题:分割位置的递归回溯,叶子结点的路径输出
  2. 组合子集问题:元素是否重复,同一树层去重,所有结点的路径输出。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1800232.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【CTF-Web】XSS漏洞学习笔记(附ctfshow web316-333题目)

XSS 跨站脚本攻击 文章目录 XSS 跨站脚本攻击What is XSS&#xff1f;How to lead XSS&#xff1f;Where is the XSS&#xff1f;CookieHow to use XSS&#xff1f;反射型XSS存储型XSSDom-Based XSS Then Lets see the XSS in CTF各种过滤绕过学习web316Web317-319Web319-321We…

[经验] 蝉联一词的含义是什么 #知识分享#职场发展

蝉联一词的含义是什么 蝉联这个词起源于古代中国&#xff0c;最初是指天子连续两年以上的年号相同。后来&#xff0c;这个词被用于形容某个人或某个团体连续多次获得某种荣誉或奖项的情况。在现代生活中&#xff0c;我们常常听到某个体育运动员蝉联冠军、某个企业蝉联业绩排行榜…

编写程序提示用户输入一个数目(例如:100)、年利率(例如:5)以及月份数(例如:6),然后显示给定月份后账户上的钱数。

(财务应用程序:复利值)假设你每月向银行账户存 100美元&#xff0c;年利率为5%&#xff0c;那么每 月利率是 0.05/12-0.00417。 第一个月之后&#xff0c;账户上的值就变成:100*(10.00417)100.417 第二个月之后&#xff0c;账户上的值就变成(100100.417)*(10.00417)-201.252 第…

MySQL(三) - 基础操作

一、索引 由于我们在使用数据库的时候&#xff0c;大部分操作的都是查询操作&#xff0c;但是我们每一次进行查询都需要遍历一遍表中所有数据&#xff0c;这会花费O(n)的时间&#xff0c;因此数据引入了“索引” 也就是在底层使用了数据结构来进行优化查询的操作&#xff0c;但…

Ubuntu流体程序编译

文章目录 前言一、换源1.1 &#xff08;任意&#xff09;终端窗口输入1.2 在终端窗口依次输入下面命令 二、编译mpap程序----安装各类库2.1 安装 Eigen 库安装Lapack、VTK、SuperLU可以按照师弟文件给出的教程 2.2 安装Lapack2.3 安装VTK2.4 安装SuperLU2.5 安装其他包2.6 安装…

45-5 护网溯源 - 远控木马样本溯源

在分析恶意样本时&#xff0c;需要查看包括作者名字、ID、IP地址、域名等在内的相关信息。 把恶意样本上传到微步、360沙箱云分析&#xff1a;样本报告-微步在线云沙箱 (threatbook.com) 动态分析 运行截图 发现该木马是与一个装机软件绑定的&#xff0c;你运行正常软件的时候…

No module named _sqlite3解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

21 - 即时食物配送 II(高频 SQL 50 题基础版)

21 - 即时食物配送 II -- sum(if(order_datecustomer_pref_delivery_date,1,0))/count(*)sum(order_datecustomer_pref_delivery_date)/count(*) -- count(*),表示数据的行数&#xff0c;如果有分组&#xff0c;为分组后数据的行数select round(100*sum(if(order_datecustomer_…

天诚公租房、人才公寓NB-IOT人脸物联网智能门锁解决方案

近期&#xff0c;全国已有超70城推出商品房“以旧换新”。各地商品房“以旧换新”主要采取国企收购、市场联动、税费补贴三种模式&#xff0c;二手房和新房市场交易活跃度均有提升。 一、人才公寓掀起建设浪潮 事实上&#xff0c;旧房被收购后将被纳入保障性租赁住房&#xf…

【悬架笔记三】1/4被动悬架垂向动力学仿真+频域特性分析

1/4被动悬架 代码&#xff1a; %书第156页、159页 clc clear close all %% 一.悬架参数 ms320; mw50; Ks22000; Cs1500; Kw195000; f00.07; %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% 二.垂向振动动力学仿真 %% 二.1.状态方程 A [0 1 0 -1;.…

查询SQL03:大的国家

问题描述 如果一个国家满足下述两个条件之一&#xff0c;则认为该国是 大国 &#xff1a; 面积至少为 300 万平方公里&#xff08;即&#xff0c;3000000 km2&#xff09;&#xff0c;或者 人口至少为 2500 万&#xff08;即 25000000&#xff09; 编写解决方案找出 大国 的国…

ubuntu 挂载新SSD盘

挂载新 SSD 盘 1 识别新硬盘 使用 lsblk 命令来识别新插入的 SSD 磁盘 lsblk输出可能如下&#xff1a; 在这个例子中 nvme1n1 是新插入的 SSD 磁盘 2 分区 接下来&#xff0c;我们需要对新磁盘进行分区。这里可以使用 parted 或 fdisk 进行分区&#xff0c;现以 parted 为…

Go微服务: 关于TCC分布式事务

TCC 分布式事务 T: Try 预处理, 尝试执行&#xff0c;完成所有的业务检查&#xff0c;做好一致性&#xff0c;预留必要的业务资源&#xff0c;做好准隔离性C: Confirm 确认&#xff0c;如果所有的分支Try都成功了, 就到了这个阶段, Confirm 是真正执行业务的过程, 不做任何业务…

国产Sora免费体验-快手旗下可灵大模型发布

自从OpenAI公布了Sora后&#xff0c;震爆了全世界&#xff0c;但由于其技术的不成熟和应用的局限性&#xff0c;未能大规模推广&#xff0c;只有零零散散的几个公布出来的一些视频。昨日&#xff0c;快手成立13周年&#xff0c;可灵&#xff08;Kling&#xff09;大模型发布&am…

BGP汇总+认证

一、BGP 的宣告问题 1、在 BGP 协议中每台运行 BGP 的设备上&#xff0c;宣告本地直连路由 2、在 BGP 协议中运行 BGP 协议的设备来宣告.通过 IGP 学习到的&#xff0c;未运行 BGP 协议设备产2、生的路由&#xff1b; 在 BGP 协议中宣告本地路由表中路由条目时,将携带本地到达这…

Facebook企业户 | Facebook公共主页经营

Facebook作为社交媒体巨头&#xff0c;拥有庞大的用户基数&#xff0c;因此&#xff0c;有效经营公共主页是获取持续流量、提升客户信任度和粘性、促进产品或服务销售与转化的关键。要优化Facebook主页&#xff0c;关注以下几点&#xff1a; 1、参与度是关键指标&#xff1a;因…

LAMPSECURITY: CTF4 靶机实战

信息收集&#xff1a; 存活扫描&#xff1a; 端口扫描&#xff1a; 服务扫描&#xff1a; web页面&#xff1a; blog页面发现注入点&#xff1a; sql注入&#xff1a; sqlmap一把梭&#xff1a; 多个参数记得打&#xff1a; 哦 ssh登录&#xff1a; 老版本的ssh&#xff0c;…

Spring 之 Lifecycle 及 SmartLifecycle

最近在看Eureka源码&#xff0c;本想快速解决这场没有硝烟的战役&#xff0c;不曾想阻塞性问题一个接一个。为正确理解这个框架&#xff0c;我不得不耐着性子&#xff0c;慢慢梳理这些让人困惑的点。譬如本章要梳理的Lifecycle和SmartLifecycle。它们均为接口&#xff0c;其中后…

【Lua】IntelliJ IDEA 写注释或选中变量单词时偶尔会选中相邻的内容或下一行内容

例如: --UI代码local a 0 当你想在a变量上方加一行 --UI代码注释时&#xff0c;会发现敲打daima中文拼音时&#xff08;还未按回车&#xff09;就会选中当前行以及下一行前半部分。 打完按空格就会变成这样子&#xff01; 原因是因为开启了英文检测&#xff0c;需要关掉它。 …

云南区块链商户平台发票助手成品

目录 1 概述2 功能对比3 项目演示图4 核心逻辑4.1智能赋码4.2 解密方法4.3 登录与检测4.4 发票金额大写转换4.5 检查登录是否失效4.6 验证码识别5 演示效果6 项目部署6.1 Web站点部署6.1.1 环境6.1.2 前端6.1.3 后端6.2 Docker部署6.2.1 构建镜像6.2.2 创建容器6.3.3 访问项目域…