当前位置: 首页 > news >正文

面试热点题:回溯算法 递增子序列与全排列 II

前言:
如果你一点也不了解什么叫做回溯算法,那么推荐你看看这一篇回溯入门,让你快速了解回溯算法的基本原理及框架

递增子序列

给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。
数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。

来源:力扣(LeetCode)递增子序列
在这里插入图片描述
由题意可得下面两点要求:

  • 递增的子序列,且元素数量大于2
  • 子序列与子序列不能相同
  • 可使用重复出现的数字

像这种需要依次取元素,然后将元素存储起来汇成总集合,期间可能还需要回退取不一样集合的题目,我们第一个想到的可以使用回溯法,那么该如何回溯呢?且看下图分析:我们使用[ 4,7,6,7 ]举例
在这里插入图片描述
在这里插入图片描述

  1. 回溯收集子集条件
    根据题意可以得知,我们只要子序列的数量大于等于2就可以
  2. 回溯终止条件
    终止条件就是达到nums.size()
  3. 单层搜索逻辑
    我们由图可以得知,虽然序列里面可能有重复的数字,但是单层我们不能取相同的数字,如果我们取了相同的数字,那么必定会存在相同的子集,所以我们单层需要去重

单层去重我们这里使用一个标记的容器 unordered_set< int > use存放已经出现过的数字


代码如下:

class Solution {
public:vector<vector<int>> arr;vector<int> _arr;void BackTracking(vector<int>& nums,int begin){if(_arr.size()>=2)//只要数据>=2就存储,我们这里不需要return{arr.push_back(_arr);}unordered_set<int> use;//标记容器for(int i=begin;i<nums.size();i++){//如果是空直接存放,然后判断别的关系if((!_arr.empty() && _arr.back()>nums[i]) || use.find(nums[i])!=use.end()){continue;}_arr.push_back(nums[i]);use.insert(nums[i]);BackTracking(nums,i+1);//不能重复使用单个数据,所以我们需要i+1_arr.pop_back();}}vector<vector<int>> findSubsequences(vector<int>& nums) {BackTracking(nums,0);return arr;}
};

全排列 II

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

来源:力扣(LeetCode)全排列 II

本题是全排列的进阶版,之前是没有重复元素,现在有重复元素,我们该如何解决呢?

在这里插入图片描述
这个题与上一题递增子序列相差不多,也是需要单层去重,且看下图:
在这里插入图片描述
相较于之前的收集元素,排列我们需要将每个元素都使用到,所以我们每次循环开始条件都为0,但是为了不使用一个使用过的元素,我们需要设置一个标记的数组,使用过一个标记一个,单层去重,是因为同一层使用相同的元素没有意义,使用相同元素,相当于递归两遍相同数据,导致出现相同子集

  • 先排序所有元素
  • 标记数组
  • 单层去重

代码如下:

class Solution {
public:vector<vector<int>> arr;vector<int> _arr;void BackTracking(vector<int>& nums,vector<bool>& use){if(_arr.size()==nums.size()){arr.push_back(_arr);return;}for(int i=0;i<nums.size();i++){//单层去重,及判断元素是否使用过if(i>0 && nums[i]==nums[i-1] && use[i-1]==false){continue;}if(use[i]==false){use[i]=true;_arr.push_back(nums[i]);BackTracking(nums,use);_arr.pop_back();use[i]=false;}}}vector<vector<int>> permuteUnique(vector<int>& nums) {sort(nums.begin(),nums.end());//需要排序,为去重做准备vector<bool> use(nums.size(),false);BackTracking(nums,use);return arr;}
};
http://www.lryc.cn/news/43208.html

相关文章:

  • 怎么找回回收站删除的文件
  • dp-打家劫舍
  • C++预处理连接
  • 3、DRF实战总结:基于类的视图APIView, GenericAPIView和GenericViewSet视图集(附源码)
  • AutoSAR PduR -AutoSAR PDU常用的使用方式【发送,接收,网关】
  • 瑟瑟发抖吧~OpenAI刚刚推出王炸——引入ChatGPT插件,开启AI新生态
  • 脉诊(切脉、诊脉、按脉、持脉)之法——入门篇
  • 【十二天学java】day09常用api介绍
  • 软件测试 - 测试用例常见面试题
  • 几种常见的API接口分页方案
  • 【Object 类的方法】
  • 留用户、补内容,在线音乐暗战不停
  • python--exec
  • 干货分享!这6个高效率办公软件,总有一个值得你收藏!
  • 代码随想录刷题-链表总结篇
  • C++:指针:什么是野指针
  • 一线大厂高并发Redis缓存架构
  • 剑指offer-二维数组中的查找
  • 怎么设计一个秒杀系统
  • 程序参数解析C/C++库 The Lean Mean C++ Option Parser
  • Java中的深拷贝和浅拷贝
  • 大文件上传
  • Python每日一练(20230327)
  • Centos7 升级内核到5.10mellanox 编译安装
  • 冯诺依曼,操作系统以及进程概念
  • 7.网络爬虫—正则表达式详讲
  • 关于位运算的巧妙性:小乖,你真的明白吗?
  • 【Android车载系列】第5章 AOSP开发环境配置
  • 个人时间管理网站—Git项目管理
  • 2023最新ChatGPT整理的40道Java高级面试题