【算法与数据结构】46、47、LeetCode全排列I, II

news2024/10/6 20:38:58

文章目录

  • 一、46.全排列I
  • 二、47.全排列II
  • 三、完整代码

所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。

一、46.全排列I

在这里插入图片描述

  思路分析:本题要求是全排列,意味着每次递归的时候startIndex都要从0开始,否则只会得到一个[1 2 3]的组合。从零开始还需要筛选掉重复的组合,引入一个used数组,使用过的元素赋值为1,跳过该循环。因为是全排列,终止条件就是单个组合中元素个数等于nums数组大小。
  程序如下

class Solution {
private:
	vector<vector<int>> result;
	vector<int> path;
	void backtracking(const vector<int>& nums, int startIndex, vector<bool>& used) {
		if (path.size() == nums.size()) {	// 终止条件
			result.push_back(path);
			return;
		}
		for (int i = startIndex; i < nums.size(); i++) {
			if (used[i]) continue;
			path.push_back(nums[i]);	// 处理节点	
			used[i] = true;
			backtracking(nums, 0, used);	// 递归
			used[i] = false;
			path.pop_back();			// 回溯
		}
	}
public:
	vector<vector<int>> permute(vector<int>& nums) {
		vector<bool> used(nums.size(), 0);
		backtracking(nums, 0, used);
		return result;
	}
};

复杂度分析:

  • 时间复杂度: O ( n ! ) O(n!) O(n!)
  • 空间复杂度: O ( n ) O(n) O(n)

二、47.全排列II

在这里插入图片描述

  思路分析:在上一题的基础之上本题中的nums元素可以是重复的,因此需要进一步去重,首先题目对全排列组合的顺序没有要求,可以对nums数组进行排序操作。i>0的条件是对nums[i-1]的限制,表示数组的索引不能小于0。nums[i]等于nums[i-1]时就是出现了重复元素,当重复元素首次在nums(排序后的)中出现时(例如[1 1 2]中的第一个1),组合不会有重复的,再次出现时(第二个1),会出现重复组合,此时的used[i-1] = 0。这道题used[i-1]=0或者used[i-1]=1都能够去重,但是used[i-1]=0的去重效率更高
  程序如下

class Solution {
private:
	vector<vector<int>> result;
	vector<int> path;
	void backtracking(const vector<int>& nums, int startIndex, vector<bool>& used) {
		if (path.size() == nums.size()) {	// 终止条件
			result.push_back(path);
			return;
		}
		for (int i = startIndex; i < nums.size(); i++) {
			if (i > 0 && nums[i] == nums[i-1] && used[i-1] == 0 || used[i]) continue;
			path.push_back(nums[i]);	// 处理节点	
			used[i] = true;
			backtracking(nums, 0, used);	// 递归
			used[i] = false;
			path.pop_back();			// 回溯
		}
	}
public:
	vector<vector<int>> permuteUnique(vector<int>& nums) {
		vector<bool> used(nums.size(), 0);
		sort(nums.begin(), nums.end());
		backtracking(nums, 0, used);
		return result;
	}
};

复杂度分析:

  • 时间复杂度: O ( n ! ∗ n ) O(n!*n) O(n!n)
  • 空间复杂度: O ( n ) O(n) O(n)

三、完整代码

// 46全排列I
# include <iostream>
# include <string>
# include <vector>
using namespace std;

class Solution {
private:
	vector<vector<int>> result;
	vector<int> path;
	void backtracking(const vector<int>& nums, int startIndex, vector<bool>& used) {
		if (path.size() == nums.size()) {	// 终止条件
			result.push_back(path);
			return;
		}
		for (int i = startIndex; i < nums.size(); i++) {
			if (used[i]) continue;
			path.push_back(nums[i]);	// 处理节点	
			used[i] = true;
			backtracking(nums, 0, used);	// 递归
			used[i] = false;
			path.pop_back();			// 回溯
		}
	}
public:
	vector<vector<int>> permute(vector<int>& nums) {
		vector<bool> used(nums.size(), 0);
		backtracking(nums, 0, used);
		return result;
	}
};

int main() {
	Solution s1;
	vector<int> nums = { 1, 2, 3 };
	vector<vector<int>> result = s1.permute(nums);
	for (vector<vector<int>>::iterator it = result.begin(); it != result.end(); it++) {
		for (vector<int>::iterator jt = (*it).begin(); jt != (*it).end(); jt++) {
			cout << *jt << " ";
		}
		cout << endl;
	}
	system("pause");
	return 0;
}
// 47全排列II
# include <iostream>
# include <string>
# include <vector>
# include <algorithm>
using namespace std;

class Solution {
private:
	vector<vector<int>> result;
	vector<int> path;
	void backtracking(const vector<int>& nums, int startIndex, vector<bool>& used) {
		if (path.size() == nums.size()) {	// 终止条件
			result.push_back(path);
			return;
		}
		for (int i = startIndex; i < nums.size(); i++) {
			if (i > 0 && nums[i] == nums[i-1] && used[i-1] == 0 || used[i]) continue;
			path.push_back(nums[i]);	// 处理节点	
			used[i] = true;
			backtracking(nums, 0, used);	// 递归
			used[i] = false;
			path.pop_back();			// 回溯
		}
	}
public:
	vector<vector<int>> permuteUnique(vector<int>& nums) {
		vector<bool> used(nums.size(), 0);
		sort(nums.begin(), nums.end());
		backtracking(nums, 0, used);
		return result;
	}
};

int main() {
	Solution s1;
	vector<int> nums = { 1, 1, 2 };
	vector<vector<int>> result = s1.permuteUnique(nums);
	for (vector<vector<int>>::iterator it = result.begin(); it != result.end(); it++) {
		for (vector<int>::iterator jt = (*it).begin(); jt != (*it).end(); jt++) {
			cout << *jt << " ";
		}
		cout << endl;
	}
	system("pause");
	return 0;
}

end

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

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

相关文章

基于 Letterize.js + Anime.js 实现炫酷文本特效

如上面gif动图所示&#xff0c;这是一个很炫酷的文字动画效果&#xff0c;文字的每个字符呈波浪式的扩散式展开。本次文章将解读如何实现这个炫酷的文字效果。 基于以上的截图效果可以分析出以下是本次要实现的主要几点&#xff1a; 文案呈圆环状扩散开&#xff0c;扩散的同时…

代驾预约小程序系统源码 :提起预约,避免排队 带完整搭建教程

大家好啊&#xff0c;又到罗峰来给大家分享好用的源码系统的时间了。今天要给大家分享的第一款代驾预约小程序源码系统。传统的代驾服务中&#xff0c;用户往往需要在酒后代驾、长途驾驶等场景下&#xff0c;面对排队等待代驾司机空闲时间的繁琐过程。这不仅浪费了用户的时间和…

excel中的OFFSET函数

介绍 OFFSET函数是确定从基点出发移动后的引用区域。它有5个参数&#xff1a; 第1个参数是引用的参考基点区域第2个参数是移动的行数&#xff0c;正数代表向下移动的行数&#xff0c;负数代表向上移动的行数第3个参数是移动的列数&#xff0c;正数代表向右移动的列数&#xf…

性价比高的台灯推荐,呼声最高的五款护眼台灯推荐

台灯可以说家家必备&#xff01;家中有上学的小孩更是需要一款好台灯&#xff0c;因为看书、写字、做作业都离不开台灯&#xff0c;一款好的台灯不仅会提供明亮的学习环境&#xff0c;而且还能保护视力&#xff0c;预防近视&#xff0c;因此&#xff0c;挑选台灯绝对不可以马虎…

企业计算机服务器中了halo勒索病毒怎么办,halo勒索病毒解密数据恢复

随着科技技术的不断提升&#xff0c;越来越多的企业开始走向数字化办公&#xff0c;让企业的生产运营得到了快速发展&#xff0c;但随之而来的网络安全威胁引起了人们的重视&#xff0c;近期&#xff0c;云天数据恢复中心陆续接到很多企业的求助&#xff0c;企业的计算机服务器…

产品经理天天跑火车,我直接和他闹翻

前言 说起产品经理与程序员&#xff0c;简直就是一对冤家。 程序员觉得产品经理不尊重技术规则&#xff0c;产品经理埋怨程序员不尊重创作用心。 一边互怼&#xff0c;一边还要合作&#xff0c;终于&#xff0c;有人忍不下去&#xff0c;动手了…… ![](https://img-blog.cs…

RFID技术在仓储物流管理中的应用方案

一、方案背景 当前市场竞争日益激烈&#xff0c;提高生产效率、降低运营成本对来说企业至关重要&#xff0c;仓储物流管理在各个行业广泛应用&#xff0c;设计和建立完善的仓储管理流程&#xff0c;提高仓储周转效率&#xff0c;减少运营资金的占用&#xff0c;将冻结的资产转…

第3关:集合操作100

任务描述相关知识编程要求测试说明 任务描述 本关任务&#xff1a;使用 集合操作解决实际问题 相关知识 1.集合并操作符 可转换为SQL 若R,S的属性名不同&#xff0c;可使用重命名使相应列名一致后进行并操作 例如&#xff1a;R(A,B,C) S(D,E,F) select A,B from R union sel…

深入了解鼠标光标的设置过程

有一位读者问了这样一个问题&#xff1a; “为什么鼠标光标的设定绑定在窗口类&#xff0c;而不是窗口上&#xff1f;” 这个问题隐含地假设了光标与窗口类相关联。虽然每个窗口类都有一个关联的光标&#xff0c;但决定使用哪个光标的是窗口。 光标设置过程在 WM_SETCURSOR 消…

用CHAT如何写视频剪辑思路?

问CHAT&#xff1a;我的行业是国学教育&#xff0c;我的工作是视频剪辑师&#xff0c;给我推荐几个剪辑思路 CHAT回复&#xff1a; 作为一个国学教育视频剪辑师&#xff0c;你的主要任务是通过剪辑创作引人入胜、富有教育性的视频。 以下是一些可能对你有帮助的剪辑思路&…

数据结构-散列表

列表&#xff08;Hash Table&#xff09;&#xff0c;又称哈希表&#xff0c;是一种数据结构&#xff0c;特点是&#xff1a;数据元素的关键字与其存储地址直接相关 例&#xff1a;有一堆数据元素&#xff0c;关键字分别为&#xff5b;19&#xff0c;14&#xff0c;23&#xff…

Session、Token、Jwt三种登录方案介绍

新开发一个应用首先要考虑的就是登录怎么去做&#xff0c;登录本身就是判断一下输入的用户名和密码与系统存储的是否一致&#xff0c;但因为Http是无状态协议&#xff0c;用户请求其它接口时是怎么判断该用户已经登录了呢&#xff1f;下面聊一个三种实现方案。 一、传统sessio…

mysql 中with的用法(2)

with递归练习主要用于表里面包含父节点id之类的 查询出对应的省份和市。 建表 CREATE TABLE tb(id VARCHAR(3), pid VARCHAR(3), name VARCHAR(64));INSERT INTO tb VALUES(002, 0, 浙江省); INSERT INTO tb VALUES(001, 0, 广东省); INSERT INTO tb VALUES(003, 002, 衢州市…

模拟实现C语言--strstr函数

模拟实现C语言–strstr函数 文章目录 模拟实现C语言--strstr函数一、strstr函数是什么&#xff1f;二、使用示例三、模拟实现3.1 模拟实现1 一、strstr函数是什么&#xff1f; 在目标字符串中寻找字符串 char * strstr ( const char *str1, const char * str2);根据语法结构&…

navicat导入已有sql表过程

已知我有一个外部的sql表&#xff0c;如图&#xff1a; 想要将其导入navicat并运行。 看一下我的navicat&#xff0c; navicat里已有的数据库并没有library&#xff0c;所以需要建立一个同名的library数据库来存储library.sql文件。 具体步骤如下&#xff1a; 在“本地连接”…

Java 反射设置List属性

使用 Java 反射可以动态地设置对象的属性值&#xff0c;包括 List 类型的属性。以下是一个示例代码&#xff0c;演示如何通过反射设置 List 类型的属性&#xff1a; 假设有一个类 Person&#xff0c;包含一个 List 类型的属性 names&#xff1a; java public class Person { …

多机器人群体的任务状态与机器人状态同步设计思路

背景技术 近年来&#xff0c;随着科学技术的发展需要&#xff0c;机器人技术不断进步。面临任务的日益复杂化&#xff0c;单机器人在很多环境下已经无法满足生产要求&#xff0c;于是国内外科研工作者对多机器人技术投入了大量关注&#xff0c;提出了利用多机器人协作来代替单机…

4步轻松搞定烦人的WPS右键菜单

安装WPS的时候不小心勾选了很多默认选项&#xff0c;结果右键菜单惨不忍睹&#xff0c;一些没用的菜单占据了大量篇幅&#xff0c;使用起来十分不方便。考虑360&#xff0c;火绒的右键菜单管理功能没搞定&#xff0c;最后在WPS的管理功能的隐藏角落找到了设置功能&#xff0c;给…

Scala---数据基础

一、数据类型 二、变量和常量的声明 定义变量或者常量的时候&#xff0c;也可以写上返回的类型&#xff0c;一般省略&#xff0c;如&#xff1a;val a:Int 10常量不可再赋值 1./** 2. * 定义变量和常量 3. * 变量 :用 var 定义 &#xff0c;可修改 4. * 常量 :用 val 定…

一文简单聊聊protobuf

目录 基本介绍 原理 同类对比 为什么要使用protobuf? 基本介绍 protobuf的全称是Protocol Buffer&#xff0c;是Google提供的一种数据序列化协议。Protocol Buffers 是一种轻便高效的结构化数据存储格式&#xff0c;可以用于结构化数据序列化&#xff0c;很适合做数据存储…