C国演义 [第四章]

第四章

  • 全排列
    • 题目理解
    • 步骤
      • 树形图
      • 递归函数
      • 递归结束条件
      • 单层逻辑
    • 代码
  • 全排列II
    • 题目理解
    • 步骤
      • 递归函数
      • 递归结束条件
      • 单层逻辑
    • 代码

全排列

力扣链接

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例 1:
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
示例 2:
输入:nums = [0,1]
输出:[[0,1],[1,0]]
示例 3:
输入:nums = [1]
输出:[[1]]

  • 提示:
    1 <= nums.length <= 6
    -10 <= nums[i] <= 10
    nums 中的所有整数 互不相同

题目理解

很明显这是用回溯算法来写的
相比较之前写的 组合 :

  • startindex — — 下一层递归的开头, 即确定下一次递归的区间, 确保不会重复

元素1在[1,2]中已经使用过了,但是在[2,1]中还要在使用一次1,所以处理排列问题就不用使用startIndex了

那我们这里的排列, 每次剩下的区间不是上一个区间的下一个— — startindex就失去了意义

那么我们这次需要一个数组来记录每个数的使用情况 — — used数组

步骤

树形图

递归函数

首先, 还是两个全局数组

vector<int> path;
vector<vector<int>> result;

递归函数的返回 还是 void, 没有startindex, 但是要用 used数组来记录每个数的使用情况

void backtracking(vector<int>& nums, vector<bool>& used)

递归结束条件

我们发现是在叶子节点接收结果, 那么就是

if(path.size() == nums.size())
{
	result.push_back(path);
	return ; // 由于是叶子节点收结果, 直接返回
}

单层逻辑

如果我们不使用 startindex 来确定下一层递归的开头, 那么我们该用什么来确定开头呢?
NO! NO!, 排列的开头就是 0, 用used数组来确定是否选取该数字

for(int i = 0; i < nums.size(); i++)
{
	// 该数字被使用过, 就跳过
	if(used[i] == false)
		continue;
		
	used[i] = true; // 使用, 那就先把它记录一下
	path.push_back(nums[i]); // 处理节点
	backtracking(nums, used); // 下一层(纵向)
	used[i] = false; // 回溯
	
}

代码

class Solution {
public:
    
    vector<int> path;
    vector<vector<int>> result;
    
    void backtracking(vector<int>& nums, vector<bool>& used)
    {
        if(path.size() == nums.size())
        {
            result.push_back(path);
            return ;
        }
        
        for(int i = 0; i < nums.size(); i++)
        {
            if(used[i] == true)
                continue;
            
            used[i] = true;
            path.push_back(nums[i]);
            backtracking(nums, used);
            path.pop_back();
            used[i] = false;
            
        }
    }
    vector<vector<int>> permute(vector<int>& nums) 
    {
        vector<bool> used(nums.size(), false);
        backtracking(nums, used);
        
        return result;
        
    }
};

全排列II

力扣链接

给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

示例 1:
输入:nums = [1,1,2]
输出:
[[1,1,2],
[1,2,1],
[2,1,1]]
示例 2:
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

  • 提示:
    1 <= nums.length <= 8
    -10 <= nums[i] <= 10

题目理解

跟上面的题目很相似, 但是 有重复的数字 && 返回不重复的全排列
⇒ 意味着我们要 去重
组合中的去重 — — 排序 + 用used来记录每个数字的使用情况
其实在 排列中的去重, 也是同样的思路

🗨️为什么要排序?

  • 通过排序, 使我们通过相邻的位置来判断是否使用过

不难发现:

  • 当 nums[i] == nums[i - 1]时, used[i - 1] = false — — 树层去重
  • 当 nums[i] == nums[i - 1]时, used[i - 1] = true — — 树枝去重

步骤

递归函数

首先, 还是两个全局数组

vector<int> path;
vector<vector<int>> result;

递归函数的返回 还是 void, 没有startindex, 但是要用 used数组来记录每个数的使用情况

void backtracking(vector<int>& nums, vector<bool>& used)

递归结束条件

我们发现是在叶子节点接收结果, 那么就是

if(path.size() == nums.size())
{
	result.push_back(path);
	return ; // 由于是叶子节点收结果, 直接返回
}

单层逻辑

	 for(int i = 0; i < nums.size(); i++)
	 {
	      // used[i - 1 ] == false是树层去重, used[i - 1 ] == true是树枝去重 
	      if(i > 0 && nums[i - 1] == nums[i] && used[i - 1] == false)
	          continue;
	      // 这里跟 组合 那里的不一样, 由于组合有startindex, 知道从剩下集合的开头
	      // 而排序, 每次都是从 0 开始, 用used数组来记录使用情况, 
	      // 那么肯定要判断一下我们当前数的使用情况
	      if(used[i] == true)
	          continue;
	      
	      used[i] = true; // 记录一下
	      path.push_back(nums[i]); // 记录节点
	      backtracking(nums, used); // 下一层递归
	      // 回溯
	      path.pop_back(); 
	      used[i] = false;
	 }
}

代码

class Solution {
public:
    
    vector<int> path;
    vector<vector<int>> result;
    
    void backtracking(vector<int>& nums, vector<bool>& used)
    {
        if(path.size() == nums.size())
        {
            result.push_back(path);
            return ;
        }
        
		 for(int i = 0; i < nums.size(); i++)
		 {
		      // used[i - 1 ] == false是树层去重, used[i - 1 ] == true是树枝去重 
		      if(i > 0 && nums[i - 1] == nums[i] && used[i - 1] == false)
		          continue;
		      // 这里跟 组合 那里的不一样, 由于组合有startindex, 知道从剩下集合的开头
		      // 而排序, 每次都是从 0 开始, 用used数组来记录使用情况, 
		      // 那么肯定要判断一下我们当前数的使用情况
		      if(used[i] == true)
		          continue;
		      
		      used[i] = true; // 记录一下
		      path.push_back(nums[i]); // 记录节点
		      backtracking(nums, used); // 下一层递归
		      // 回溯
		      path.pop_back(); 
		      used[i] = false;
		 }
    }
        
    vector<vector<int>> permuteUnique(vector<int>& nums) 
    {
        sort(nums.begin(), nums.end()); // 一定记得要排序
        vector<bool> used(nums.size(), false); // 都先初始化为false -- -- 没用过
        backtracking(nums, used);
        
        return result;
    }
};

天地转,光阴迫,一万年太久,只争朝夕。一一毛泽东

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【前端】导航栏html(ul+li)/css/js(jq)

引入jq <script src"https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script> css代码 <style>ul {list-style: none;margin: 0;padding: 0;}li {cursor: pointer;}.color-white {color: #FFFFFF !important;background-color: rgb…

Python工具箱系列(三十七)

二进制文件操作&#xff08;上&#xff09; python比较擅长与文本相关的操作。但现实世界中&#xff0c;对于非文本消息的处理也很普遍。例如&#xff1a; ◆通过有线、无线传递传感器获得的测量数据。 ◆卫星通过电磁波发送测量数据。 ◆数据中心的数万台服务器发送当前CP…

Eureka注册失败解决

根据查看网上资料发现是服务端自己自己注册了&#xff0c;所以需要自己关闭服务端注册 加上两行代码 fetch-registry: false register-with-eureka: false 即可注册成功

基于Java+SpringBoot+Vue前后端分离摄影分享网站平台系统

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

python爬虫-逆向实例小记-3

注意&#xff01;&#xff01;&#xff01;&#xff01;某数据网站逆向实例仅作为学习案例&#xff0c;禁止其他个人以及团体做谋利用途&#xff01;&#xff01;&#xff01;&#xff01; 案例分析 第一步&#xff1a;分析页面。查看响应内容&#xff0c;内容加密 第二步&am…

【周末闲谈】浅谈“AI+算力”

随着人工智能技术的飞速发展&#xff0c;“AI算力”的结合应用已成为科技行业的热点话题&#xff0c;甚至诞生出“AI算力最强龙头“的网络热门等式。该组合不仅可以提高计算效率&#xff0c;还可以为各行各业带来更强大的数据处理和分析能力&#xff0c;从而推动创新和增长。 文…

k8s中kubectl陈述式资源管理

陈述式管理资源的方法 1&#xff0c;陈述时资源管理集群资源的唯一入口是通过相应的方法调用的apiserver的接口 2&#xff0c;kubectl 是官方的ctl命令&#xff0c;用于与 apiserver 进行通信&#xff0c;将用户在命令行输入的命令&#xff0c;组织并转化为 apiserver 能识别…

【跨域认证】详解JWT,JWT是什么?

JSON Web Token&#xff08;缩写 JWT&#xff09;是目前最流行的跨域认证解决方案&#xff0c;本文介绍它的原理和用法。 一、跨域认证的问题 互联网服务离不开用户认证。一般流程是下面这样。 1、用户向服务器发送用户名和密码。 2、服务器验证通过后&#xff0c;在当前对话&…

Transformer面试题总结

1.框架 Transformer和seq2seq一样由解码器和编码器组成&#xff0c;用多头注意力替换编码器和解码器架构中最常用的循环层 1.1 编码器&#xff1a;编码器有一堆N6的相同层组成&#xff0c;每一层有两个子层&#xff0c;第一个子层包含多头注意力机制&#xff0c;第二个子层是前…

React环境安装配置

React环境安装配置 一、前提二、React安装 一、前提 安装本地React环境需要Node.js&#xff0c;如果具有Node环境跳过即可。如果没有安装则可参考该篇文章安装Node环境&#xff0c;点击查看 二、React安装 全局安装React 首先打开命令行&#xff0c;建议以管理员身份输入命…

Golang语言介绍、环境搭建以及编译工具( CDN 加速代理)

Go 语言是非常有潜力的语言&#xff0c;是因为它的应用场景是目前互联网非常热门的几个领域&#xff0c;比如 WEB 开发、区块链开发、大型游戏服务端开发、分布式/云计算开发。国内比较知名的B 站就是用 Go 语言开发的&#xff0c;像 Goggle、阿里、京东、百度、腾讯、小米、36…

人工神经网络太简陋了,《Science》揭露,神经元树突也隐含计算能力

本篇文章是博主在人工智能等领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对人工智能等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅解。文章分类在学习摘录和笔记专…

[论文阅读] (31)李沐老师视频学习——4.研究的艺术·理由、论据和担保

《娜璋带你读论文》系列主要是督促自己阅读优秀论文及听取学术讲座&#xff0c;并分享给大家&#xff0c;希望您喜欢。由于作者的英文水平和学术能力不高&#xff0c;需要不断提升&#xff0c;所以还请大家批评指正&#xff0c;非常欢迎大家给我留言评论&#xff0c;学术路上期…

【微服务】什么是微服务?-- 全面了解微服务架构

What is Microservices — Edureka 您有没有想过&#xff0c;什么是微服务以及扩展行业如何与它们集成&#xff0c;同时构建应用程序以满足客户的期望&#xff1f; 要了解什么是微服务&#xff0c;您必须了解如何将单体应用程序分解为独立打包和部署的小型微型应用程序。本文将…

【Docker】基于jib插件,实现Docker部署springboot项目

文章目录 创建springboot项目jib插件介绍使用打tar包 Docker部署springboot项目 在工作中&#xff0c;作为一名后端开发人员&#xff0c;项目部署运维的事我们可能都要同时干&#xff0c;今天想跟大家聊聊关于springboot项目使用docker部署相关操作。后期还会跟大家分享docker-…

服务器垃圾怎样清理?C盘垃圾如何清理?

好多人都在问电脑垃圾如何清理&#xff1f;服务器的垃圾清理是系统维护中必不可少的一项任务&#xff0c;而C盘垃圾的清理同样也是必须要做的任务之一。那么&#xff0c;如何一键清理服务器垃圾&#xff0c;C盘垃圾如何清理呢&#xff1f;今天&#xff0c;我会以服务器助手为例…

动态ip与静态ip的概念、区别、应用场景

动态ip与静态ip的区别 前言一、介绍IP地址的概念和作用1.1、IP地址的定义1.2、IP地址的作用 二、动态IP和静态IP的区别2.1、动态IP和静态IP的定义2.2、动态IP和静态IP的特点2.3、动态IP和静态IP的优缺点比较 三、动态IP和静态IP的应用场景3.1. 动态IP的应用场景3.2. 静态IP的应…

【Spring Boot】Spring Boot配置文件详情

前言 Spring Boot是一个开源的Java框架&#xff0c;用于快速构建应用程序和微服务。它基于Spring Framework&#xff0c;通过自动化配置和约定优于配置的方式&#xff0c;使开发人员可以更快地启动和运行应用程序。Spring Boot提供了许多开箱即用的功能和插件&#xff0c;包括嵌…

LeetCode 75 —— 62. 不同路径

LeetCode 75 —— 62. 不同路径 一、题目描述&#xff1a; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &…

【图像处理】去雾源码收集(halcon、python、C#、VB、matlab)

【图像处理】去雾代码收集&#xff08;附halcon、python、C#、VB、matlab源码&#xff09; 一、halcon算法1.1 halcon算法源码1.2 halcon算法效果图![在这里插入图片描述](https://img-blog.csdnimg.cn/8ad5217a59be4de29b5a7b6eee997b85.png#pic_center) 二、opencv算法2.1 py…