代码随想录第二十五天(一刷C语言)|递增子序列全排列全排列II

news2024/12/30 3:00:26

创作目的:为了方便自己后续复习重点,以及养成写博客的习惯。

组合和排列问题是在树形结构的叶子节点上收集结果,而子集问题就是取树上所有节点的结果

一、递增子序列

思路:参考carl文档

        已经是递增序列故而不用排序,元素不能重复使用,需要startIndex,调整下一层递归的起始位置。在遍历树形结构找每一个节点,可以通过startIndex结束递归,可以不加终止条件。通过树形结构了解到,同一层元素使用过就不能再使用了。

ledcode题目:https://leetcode.cn/problems/non-decreasing-subsequences/

AC代码:

int* path;
int pathTop;
int** ans;
int ansTop;
int* length;
//将当前path中的内容复制到ans中
void copy() {
    int* tempPath = (int*)malloc(sizeof(int) * pathTop);
    memcpy(tempPath, path, pathTop * sizeof(int));
    length[ansTop] = pathTop;
    ans[ansTop++] = tempPath;
}

//查找uset中是否存在值为key的元素
int find(int* uset, int usetSize, int key) {
    int i;
    for(i = 0; i < usetSize; i++) {
        if(uset[i] == key)
            return 1;
    }
    return 0;
}

void backTracking(int* nums, int numsSize, int startIndex) {
    //当path中元素大于1个时,将path拷贝到ans中
    if(pathTop > 1) {
        copy();
    }
    int* uset = (int*)malloc(sizeof(int) * numsSize);
    int usetTop = 0;
    int i;
    for(i = startIndex; i < numsSize; i++) {
        //若当前元素小于path中最后一位元素 || 在树的同一层找到了相同的元素,则continue
        if((pathTop > 0 && nums[i] < path[pathTop - 1]) || find(uset, usetTop, nums[i]))
            continue;
        //将当前元素放入uset
        uset[usetTop++] = nums[i];
        //将当前元素放入path
        path[pathTop++] = nums[i];
        backTracking(nums, numsSize, i + 1);
        //回溯
        pathTop--;
    }
}

int** findSubsequences(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    //辅助数组初始化
    path = (int*)malloc(sizeof(int) * numsSize);
    ans = (int**)malloc(sizeof(int*) * 33000);
    length = (int*)malloc(sizeof(int*) * 33000);
    pathTop = ansTop = 0;

    backTracking(nums, numsSize, 0);

    //设置数组中返回元素个数,以及每个一维数组的长度
    *returnSize = ansTop;
    *returnColumnSizes = (int*)malloc(sizeof(int) * ansTop);
    int i;
    for(i = 0; i < ansTop; i++) {
        (*returnColumnSizes)[i] = length[i];
    }
    return ans;
}

二、全排列

思路:参考carl文档

        处理排列问题就不需要使用startIndex而是需要一个used数组,标记已经选元素。当收集元素的数组path的大小和nums数组一样大时,说明找到了一个全排列,也表示到达了叶子节点。排列问题每次都要从头开始搜索,used数组就是记录path里有哪些元素使用了,一个排列里一个元素只能使用一次。

lecode题目:https://leetcode.cn/problems/permutations/

AC代码:

int* path;
int pathTop;
int** ans;
int ansTop;

//将used中元素都设置为0
void initialize(int* used, int usedLength) {
    int i;
    for(i = 0; i < usedLength; i++) {
        used[i] = 0;
    }
}

//将path中元素拷贝到ans中
void copy() {
    int* tempPath = (int*)malloc(sizeof(int) * pathTop);
    int i;
    for(i = 0; i < pathTop; i++) {
        tempPath[i] = path[i];
    }
    ans[ansTop++] = tempPath;
}

void backTracking(int* nums, int numsSize, int* used) {
    //若path中元素个数等于nums元素个数,将nums放入ans中
    if(pathTop == numsSize) {
        copy();
        return;
    }
    int i;
    for(i = 0; i < numsSize; i++) {
        //若当前下标中元素已使用过,则跳过当前元素
        if(used[i])
            continue;
        used[i] = 1;
        path[pathTop++] = nums[i];
        backTracking(nums, numsSize, used);
        //回溯
        pathTop--;
        used[i] = 0;
    }
}

int** permute(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    //初始化辅助变量
    path = (int*)malloc(sizeof(int) * numsSize);
    ans = (int**)malloc(sizeof(int*) * 1000);
    int* used = (int*)malloc(sizeof(int) * numsSize);
    //将used数组中元素都置0
    initialize(used, numsSize);
    ansTop = pathTop = 0;

    backTracking(nums, numsSize, used);

    //设置path和ans数组的长度
    *returnSize = ansTop;
    *returnColumnSizes = (int*)malloc(sizeof(int) * ansTop);
    int i;
    for(i = 0; i < ansTop; i++) {
        (*returnColumnSizes)[i] = numsSize;
    }
    return ans;
}

三、全排列II

思路:参考carl文档

         与全排列的区别在于给定一个可重复数字的序列,要返回所有不重复的全排列(去重)。而且去重一定要对元素进行排序,通过相邻的节点来判断元素是否重复使用了。     同一树层的前一位(nums[i-1])如果使用过,那么就进行去重。

ledcode题目:https://leetcode.cn/problems/permutations-ii/description/

AC代码:

//临时数组
int *path;
//返回数组
int **ans;
int *used;
int pathTop, ansTop;

//拷贝path到ans中
void copyPath() {
    int *tempPath = (int*)malloc(sizeof(int) * pathTop);
    int i;
    for(i = 0; i < pathTop; ++i) {
        tempPath[i] = path[i];
    }
    ans[ansTop++] = tempPath;
}

void backTracking(int* used, int *nums, int numsSize) {
    //若path中元素个数等于numsSize,将path拷贝入ans数组中
    if(pathTop == numsSize)
        copyPath();
    int i;
    for(i = 0; i < numsSize; i++) {
        //若当前元素已被使用
        //或前一位元素与当前元素值相同但并未被使用
        //则跳过此分支
        if(used[i] || (i != 0 && nums[i] == nums[i-1] && used[i-1] == 0))
            continue;

        //将当前元素的使用情况设为True
        used[i] = 1;
        path[pathTop++] = nums[i];
        backTracking(used, nums, numsSize);
        used[i] = 0;
        --pathTop;
    }
}

int cmp(void* elem1, void* elem2) {
    return *((int*)elem1) - *((int*)elem2);
}

int** permuteUnique(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    //排序数组
    qsort(nums, numsSize, sizeof(int), cmp);
    //初始化辅助变量
    pathTop = ansTop = 0;
    path = (int*)malloc(sizeof(int) * numsSize);
    ans = (int**)malloc(sizeof(int*) * 1000);
    //初始化used辅助数组
    used = (int*)malloc(sizeof(int) * numsSize);
    int i;
    for(i = 0; i < numsSize; i++) {
        used[i] = 0;
    }

    backTracking(used, nums, numsSize);

    //设置返回的数组的长度
    *returnSize = ansTop;
    *returnColumnSizes = (int*)malloc(sizeof(int) * ansTop);
    int z;
    for(z = 0; z < ansTop; z++) {
        (*returnColumnSizes)[z] = numsSize;
    }
    return ans;
}

全篇后记:

        在明确思路的前提下,才能开始做,不然总会去走回头路。

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

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

相关文章

STL源码分析之allocate

空间配置函数allocate //空间配置函数的内部实现原理 //allocate()函数&#xff0c;首先判断区块大小&#xff0c;大于128bytes就调用第一级配置器&#xff0c;小于128bytes就检查对应的free list. //如果free list之内有可用的区块&#xff0c;就直接拿来用&#xff0c;如果没…

Axure RP免费版:详细信息抢先知道

Axure RP收费吗&#xff1f; 是的&#xff0c;AxureRP是一种收费的原型设计工具。它提供了两种选择&#xff1a;免费试用版和付费版。免费试用版可免费使用30天&#xff0c;功能与付费版相同&#xff0c;但导出时会有Axure水印&#xff0c;文件无法保存。付费版分为Pro版和Tea…

实现了一个简单的卡通渲染效果

介绍 简单参考下实现了基本卡通着色渲染效果&#xff1a; 主要包含了描边和内部色块 开始构建了一个场景用于展示光线的变化&#xff0c;并放置了一个角色。 npr_1 接下去加入描边的效果&#xff0c;可以感觉到人物轮廓变明显了。 npr_2 然后再加入了内部的色块变化并调小了点…

Android集成科大讯飞语音识别与语音唤醒简易封装

一、语音唤醒部分 1、首先在科大讯飞官网注册开发者账号 控制台-讯飞开放平台 2、配置唤醒词然后下载sdk 3、选择对应功能下载 4、语音唤醒lib包全部复制到工程目录下 5、把语音唤醒词文件复制到工程的assets目录 6、复制对应权限到AndroidManifest.xml中 <uses-permissio…

同旺科技 USB TO RS-485 定制款适配器--- 拆解(二)

内附链接 1、USB TO RS-485 定制款适配器 ● 支持USB 2.0/3.0接口&#xff0c;并兼容USB 1.1接口&#xff1b; ● 支持USB总线供电&#xff1b; ● 支持Windows系统驱动&#xff0c;包含WIN10 / WIN11系统32 / 64位&#xff1b; ● 支持Windows RT、Linux、Mac OS X、Windo…

【开源】基于Vue+SpringBoot的固始鹅块销售系统

项目编号&#xff1a; S 060 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S060&#xff0c;文末获取源码。} 项目编号&#xff1a;S060&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 鹅块类型模块2.3 固…

CentOS关闭 swap分区

临时关闭swap分区: swapoff -a # 永久关闭swap分区: sed -ri s/.*swap.*/#&/ /etc/fstab 或者 vim /etc/fstab free -m

《opencv实用探索·八》图像模糊之均值滤波、高斯滤波的简单理解

1、前言 什么是噪声&#xff1f; 该像素与周围像素的差别非常大&#xff0c;导致从视觉上就能看出该像素无法与周围像素组成可识别的图像信息&#xff0c;降低了整个图像的质量。这种“格格不入”的像素就被称为图像的噪声。如果图像中的噪声都是随机的纯黑像素或者纯白像素&am…

批量免费AI写作工具,批量免费AI写作软件

人工智能&#xff08;AI&#xff09;的应用在各个领域不断创新。面对繁重的写作任务,我们应该怎么完成&#xff1f;本文将专心分享批量免费AI写作的方法、工具以及选择时需要注意的事项。 批量免费AI写作的方法 利用开源AI模型 一种常见的批量免费AI写作方法是利用开源的AI模…

Unity中动态合批

文章目录 前言一、动态合批的规则1、材质相同是合批的前提&#xff0c;但是如果是材质实例的话&#xff0c;则一样无法合批。2、支持不同网格的合批3、动态合批需要网格支持的顶点条件二、我们导入一个模型并且制作一个Shader&#xff0c;来测试动态合批1、我们选择模型的 Mesh…

企业级SQL开发:如何审核发布到生产环境的SQL性能

自从上世纪 70 年代数据库开始普及以来&#xff0c;DBA 们就不停地遭遇各种各样的数据库管理难题&#xff0c;其中最为显著的&#xff0c;可能就是日常的开发任务中&#xff0c;研发人员们对于核心库进行变更带来的一系列风险。由于针对数据库的数据变更是一项非常常见的任务&a…

老师如何管理课堂纪律?

1 .与学生建立良好的师生关系&#xff0c;加强沟通。建立互相尊重的关系&#xff0c;让学生感受到老师的理解和关心 2. 制定合理的课堂规则和纪律&#xff0c;让学生了解规则的重要性和必要性&#xff0c;并遵守规则。 3. 在课堂上保持秩序&#xff0c;避免嘈杂的行为和讨论。…

MAMBA介绍:一种新的可能超过Transformer的AI架构

有人说&#xff0c;“理解了人类的语言&#xff0c;就理解了世界”。一直以来&#xff0c;人工智能领域的学者和工程师们都试图让机器学习人类的语言和说话方式&#xff0c;但进展始终不大。因为人类的语言太复杂&#xff0c;太多样&#xff0c;而组成它背后的机制&#xff0c;…

如何使用Python核对文件夹内的文件

说明&#xff1a;日常工作中&#xff0c;我们经常会遇到这样的场景&#xff1a;核对A、B文件夹中文件的差异&#xff0c;找出A、B文件夹中不同部分的文件&#xff1b; 本文介绍如何使用Python来实现&#xff1b; 第一步&#xff1a;获取文件清单 首先&#xff0c;我们要获取…

Go 语言中的反射机制

欢迎大家到我的博客浏览&#xff0c;更好的阅读体验请点击 反射 | YinKais Blog 反射在大多数的应用和服务中并不常见&#xff0c;但是很多框架都依赖 Go 语言的反射机制简化代码。<!--more-->因为 Go 语言的语法元素很少、设计简单&#xff0c;所以它没有特别强的表达能…

基于c++版本数组队列改-Python数组队列的总结

##队列部分-猫猫排队 是一种遵循先入先出规则的线性数据结构。 是一种模拟排队现象&#xff0c;新来的人不断加入到队列尾部&#xff0c;而位于队列头部的人不断离开。 ##抽象数据类型队列的定义 队列是一种先进先出的线性表&#xff0c;它只允许在表的一端进行插入&#xf…

Word使用相关——(待完善)

1.word 怎样删除分节符 2.word 怎样删除目录中的分节符 欢迎使用Markdown编辑器 你好&#xff01; 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章&#xff0c;了解一下Markdown的基本语法知识。 新的改变 我…

Linux上使用独立显卡Tesla T4(测试视频压缩)

背景 将视频处理程序单独部署至K8S之外&#xff0c;使用独立GPU显卡的一台服务器上。 需事先对GPU性能做简单测试。 已通过zabbix对Linux进行了系统资源监控。 已通过PrometheusGrafana对显卡Tesla T4做了性能监控。 逐步补充&#xff0c;稍等 2023年12月6日 操作 查看当前…

【GPU】linux 安装、卸载 nvidia 显卡驱动、cuda 的官方文档、推荐方式(runfile)

文章目录 1. 显卡驱动1.1. 各版本下载地址1.2. 各版本文档地址1.3. 安装、卸载方式 2. CUDA2.1. 各版本下载地址2.2. 各版本文档地址2.3. 安装、卸载方式2.4. 多版本 CUDA 切换方式 1. 显卡驱动 1.1. 各版本下载地址 https://www.nvidia.com/Download/Find.aspx?langzh-cn 1…

【zip密码】如何删除zip压缩包的密码?

大家都知道压缩包可以进行加密&#xff0c;但是当我们不需要加密压缩包的时候&#xff0c;该如何删除zip压缩包密码呢&#xff1f;那么zip压缩包密码取消都有什么方法呢&#xff1f;今天将方法总结分享给大家。 最原始的方法&#xff0c;就是通过解压文件&#xff0c;将解压出…