C国演义 [第四章]

news2024/9/21 4:33:44

第四章

  • 全排列
    • 题目理解
    • 步骤
      • 树形图
      • 递归函数
      • 递归结束条件
      • 单层逻辑
    • 代码
  • 全排列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;
    }
};

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

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

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

相关文章

简要介绍 | 深度学习中的自注意力机制:原理与挑战

注1&#xff1a;本文系“简要介绍”系列之一&#xff0c;仅从概念上对深度学习中的自注意力机制进行非常简要的介绍&#xff0c;不适合用于深入和详细的了解。 注2&#xff1a;"简要介绍"系列的所有创作均使用了AIGC工具辅助 深度学习中的自注意力机制&#xff1a;原…

android jetpack databinding的基本使用(java)

目录 databing的基本使用二级页面的绑定自定义BindingAdapter自定义BinddingAdapter的可选旧值双向绑定使用ObservableField来进行双向绑定 在recycleview中使用databinding databing的基本使用 开启databing android {........dataBinding{enable true} }修改布局文件 为布…

Unity UGUI6——UGUI进阶

一、UI 事件监听接口 ​ 目前所有的控件都只提供了常用的事件监听列表 ​ 如果想做一些类似长按&#xff0c;双击&#xff0c;拖拽等功能是无法制作的&#xff0c;或者想让 Image 和 Text&#xff0c;RawImage 三大基础控件能够响应玩家输入也是无法制作的 ​ 而事件接口就是…

Elasticsearch 基本使用(三)条件查询

条件查询 单条件查询matchdebug 查看分词结果match_phrase 多条件查询bool 子元素区别 单条件查询 match match 匹配字段&#xff0c;会对条件分词&#xff0c;然后每个词以or的关系在文档倒排索引内进行查询 GET bank/_search {"query": {"match": {&q…

一起学SF框架系列6.1-模块core-Resource

Java虽然提供了java.net.URL类和各种URL前缀处理程序来负责处理对各种资源的访问&#xff0c;但对于低级别资源的访问来说还是不够充分。例如&#xff0c;没有标准化的实现可用于访问需要从类路径中获取或者相对于一个ServletContext的资源&#xff1b;也没有检查所指向的资源是…

火影手游 问答题小抄

文章目录 Part.I IntroductionPart.II 一些常识Chap.I 基础常识Chap.II 人物相关Chap.III 原作相关Chap.III 游戏相关 Part.III 奥义 & 技能Chap.I S 忍Chap.II A 忍Chap.III B 忍Chap.IV C 忍 Part.IV 针对活动Chap.I 组织樱花祭Chap.II 樱花问答 Pary.V 名言Reference Pa…

群辉DSM7.2安装svn服务

Part1前言 今天研究了一晚上使用群辉安装svn&#xff0c;确实挺多坑的&#xff0c;总结记录一下。我的型号是DS220&#xff0c;版本为DSM 7.2 Part2安装docker 首先打开套件中心&#xff0c;如下图&#xff0c;检索docker 然后点击安装&#xff0c;安装之后打开如下&#xff1a…

Clickhouse之物化视图分享

前言 ClickHouse广泛用于用户和系统日志查询场景中&#xff0c;主要针对于OLAP场景&#xff0c;为业务方提供稳定高效的查询服务。在业务场景下&#xff0c;数据以不同的格式、途径写入到clickhouse。用传统JOIN方式查询海量数据&#xff0c;通常有如下痛点: 每个查询的代码冗…

【TOP生物信息】基于Scanpy的单细胞数据质控、聚类、标注

扫码关注下方公粽号&#xff0c;回复推文合集&#xff0c;获取400页单细胞学习资源&#xff01; 「写在前面」 Python作为一种高级编程语言&#xff0c;被广泛用于单细胞数据分析&#xff0c;有着以下的优势&#xff1a; 「大量的生物信息学库&#xff1a;」 Python拥有大量的…

【UE 从零开始制作坦克】6-坦克开炮

效果 步骤 1. 添加初学者内容包&#xff08;需要用到其中的音效和粒子效果&#xff09; 2. 接下来制作坦克的炮弹 首先新建一个Actor蓝图类&#xff0c;作为所有发射物体&#xff08;炮弹、机枪子弹等&#xff09;的父类&#xff0c;这里命名为“TotalCategoryOfProjectile”…

从清华高材生拿到百万年薪offer说起

这几天在脉脉上看到一个很火的帖子&#xff0c;帖子内容是一位清华姚班毕业的博士&#xff0c;透露其拿到「亚马逊应用科学家」的offer&#xff0c;Base 110k/月&#xff0b;股票400K分四年给&#xff0c;还有195k的签字费。 清华姚班毕业薪资 看到这张截图博主留下了羡慕的泪…

搞懂了,React 中原来要这样测试自定义 Hooks

React 中自定义的 Hooks 为开发者提供了重用公共方法的能力。然而&#xff0c;如果你是一个测试新手的话&#xff0c;测试这些钩子可能会很棘手。本文中&#xff0c;我们将探索如何使用 React Testing Library 测试库来测试自定义钩子。 如何测试 React 组件 开始前&#xff…

【统计模型】生存分析基本知识介绍

目录 一、生存分析介绍 1.生存分析用途 2.传统方法在分析随访资料时的困难 &#xff08;1&#xff09;生存时间和生存结局都是我们关心的因素 &#xff08;2&#xff09;存在大量失访 &#xff08;3&#xff09;显然&#xff0c;将失访数据无论是算作死亡还是存活都不合理…

CSS基础学习--20 提示工具(Tooltip)

一、定义 提示工具在鼠标移动到指定元素后触发&#xff0c;总共四种样式实例&#xff1a; 二、基础提示框(Tooltip) 提示框在鼠标移动到指定元素上显示 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>CSS基础学习-提…

【RV1126】IIC驱动--EEPROM

文章目录 原理图查找空闲的I2CEEPROM芯片改设备树编写驱动驱动端设备端驱动端和设备端编译成驱动模块应用层的测试代码 原理图查找空闲的I2C 由上面可以知道&#xff0c;空闲了I2C4接口&#xff0c;然后也引出来了。 再找原理图找到具体引脚&#xff1a; I2C4_SCL&#xff1…

第 5 章 机器学习技术的应用(下)

全文目录 机器学习技术的实施方法 预测阶段效果监控 离线预测在线预测 监控点击率的稳定性 真实点击率的稳定性 计算相邻两个区间内点击率分布的 PSI(Population Stability Index, 群体稳定性指标), 小于 0.1 可认为数据相对稳定;预测点击率的稳定性 与系统本身和用户发生变…

Dice Loss

导读 ​ Dice Loss是由 Dice 系数而得名的&#xff0c;Dice系数是一种用于评估两个样本相似性的度量函数&#xff0c;其值越大意味着这两个样本越相似&#xff0c;Dice系数的数学表达式如下&#xff1a; Dice 2 ∣ X ∩ Y ∣ ∣ X ∣ ∣ Y ∣ \text { Dice }\frac{2|X \ca…

Windows10完全卸载oracle19c

Windows10完全卸载oracle19c 1.停止服务2.卸载产品3.清理注册表4.清理环境变量5.清理文件夹 1.停止服务 winR输入service.msc进入服务列表&#xff0c;停止所有的服务 2.卸载产品 点击开始菜找到Oracle&#xff0c;然后点击Oracle安装产品&#xff0c;再点击Universal Inst…

如何安装PHP框架

目录 什么是PHP框架 第一步 安装PHP依赖包 第二步 导入PHP相关包 第三步 解包并切换进指定目录 第四步 在PHP目录内编译安装 第五步 编译 第六步 拷贝配置文件进行编辑 第七步 修改时区 第八步 修改文件指定路径 第九步 将命令加入指定目录进行识别 第十步 进入配置…

【Flutter】Audioplayers 4.1.0 简要使用说明

文章目录 一、前言二、安装和设置三、基本使用1.创建 AudioPlayer 实例2.设置音频源3.控制播放 四、示例代码五、总结 一、前言 Audioplayers 是一个非常实用的 Flutter 插件&#xff0c;它可以帮助我们在 Flutter 应用中播放音频。无论你是想在你的应用中添加背景音乐&#x…