全网最详细的排列组合系列算法题整理

2023-05-16

写在前面

LeetCode上面排列组合系列几乎所有题目放在一起整理了一下。

面试题 08.07. 无重复字符串的排列组合

无重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合,字符串每个字符均不相同。

示例:

输入:S = “qwe”

输出:[“qwe”, “qew”, “wqe”, “weq”, “ewq”, “eqw”]

提示:

  1. 字符都是英文字母。
  2. 字符串长度在[1, 9]之间。

解法:

一位一位插入字符,插入到每一个空当里面。这种递归的方法,比交换要清晰不少。

代码:

class Solution {
private:
    vector<string> res;
public:
    void dfs(string& t, string& s, int k){
        if(t.length()==s.length()){
            res.push_back(t);
            return;
        }
        for(int i=0; i<=t.size(); i++){
            string tmp = t.substr(0,i) + s[k] + t.substr(i);
            dfs(tmp,s,k+1);
        }
    }
    vector<string> permutation(string s) {
        if(s.empty()) return {};
        string t = "";
        t += s[0];
        dfs(t, s, 1);
        return res;
    }
};

46. 全排列

给定一个 没有重复 数字的序列,返回其所有可能的全排列。

示例:

输入: [1,2,3]

输出:

[

 [1,2,3],

 [1,3,2],

 [2,1,3],

 [2,3,1],

 [3,1,2],

 [3,2,1]

]

解法:

和上题一样都是全排列,但是变成了一串数字。处理方法和上一题就不一样了,因为字符串插入很简单,但是数组插入的话就会很费时间,所以就不能投机了,这里用最经典的回溯思路来进行数字的全排列。

算法用dfs,用used数组记录当前数字是否选过,然后一直选到不能选为止,记得要恢复状态。

代码:

class Solution {
private:
    vector<vector<int>> res;
public:
    void dfs(vector<int>& tmp, vector<bool>& used, vector<int>& nums){
        if(tmp.size()==used.size()){
            res.push_back(tmp);
            return;
        }
        for(int i=0; i<used.size(); i++){
            if(used[i]==false){
                used[i] = true;
                tmp.push_back(nums[i]);
                dfs(tmp,used,nums);
                used[i] = false;//恢复状态
                tmp.pop_back();
            }
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        res.clear();
        if(nums.empty()) return res;
        vector<int> tmp;
        vector<bool> used(nums.size(),false);
        dfs(tmp,used,nums);
        return res;
    }
};

77. 组合

给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。

示例:

输入: n = 4, k = 2

输出:

[

 [2,4],

 [3,4],

 [2,3],

 [1,2],

 [1,3],

 [1,4],

]

解法:

组合和排列本来就是分不开的,所以思路和代码和上一题差别不大,判断条件上面有些改变,个数到k就可以插入,然后因为是组合不是排列,所以要判重,这里因为是1~n,所以只要一直递增就行了。

代码:

class Solution {
private:
    vector<vector<int>> res;
public:
    void dfs(vector<int>& tmp, vector<bool>& used, int k){
        if(tmp.size()==k){
            res.push_back(tmp);
            return;
        }
        int p = (tmp.empty())?1:tmp.back()+1;
        for(int i=p; i<used.size(); i++){
            if(used[i]==false){
                tmp.push_back(i);
                used[i] = true;
                dfs(tmp,used,k);
                tmp.pop_back();
                used[i] = false;
            }
        }
    }
    vector<vector<int>> combine(int n, int k) {
        vector<bool> used(n+1,false);
        vector<int> tmp;
        dfs(tmp,used,k);
        return res;
    }
};

47. 全排列 II

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

示例:

输入: [1,1,2]

输出:

[

 [1,1,2],

 [1,2,1],

 [2,1,1]

]

解法:

和全排列代码类似,但是要考虑重复的情况,每一层dfs的时候,剪掉重复的元素就行了,不重复搜。

代码:

class Solution {
private:
    vector<vector<int>> res;
public:
    void dfs(vector<int>& tmp, vector<bool>& used, vector<int>& nums){
        if(tmp.size()==used.size()){
            res.push_back(tmp);
            return;
        }
        for(int i=0; i<used.size(); i++){
            if(i>0 && nums[i]==nums[i-1] && !used[i-1])
                continue;
            if(!used[i]){
                used[i] = true;
                tmp.push_back(nums[i]);
                dfs(tmp,used,nums);
                used[i] = false;
                tmp.pop_back();
            }
        }
    }
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        res.clear();
        if(nums.empty()) return res;
        sort(nums.begin(),nums.end());
        vector<int> tmp;
        vector<bool> used(nums.size(),false);
        dfs(tmp,used,nums);
        return res;
    }
};

31. 下一个排列

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。

1,2,3 → 1,3,2

3,2,1 → 1,2,3

1,1,5 → 1,5,1

解法:

求字典序选排列的下一个,这里先找数学规律。

首先可以观察到,如果序列是降序的,说明已经是最后一个的排列了,这时候下一个就是第一个有序的数列。

然后如果不是降序的,这时候从后往前找第一个上升的位置,a[i-1]<a[i]的位置,然后再寻找i-1后面比a[i-1]大的最小的那个数的位置j(有点拗口,细品一下不难理解),交换a[i-1],a[j],然后把a[i-1]后面的数从小到大排序。

代码:

class Solution {
public:
    void nextPermutation(vector<int>& a) {
        if(a.empty() || a.size()<=1) return;
        int p = a.size()-1;
        while(p-1>=0 && a[p]<=a[p-1])//寻找升序位置
            p--;
        if(p>0){//判断是不是降序
            int q = p;
            for(int j = p+1; j<a.size(); j++)
                if(a[j]>a[p-1] && a[j]<a[q]){//寻找第二个位置
                    q = j;
                }
            int t = a[q];
            a[q] = a[p-1];
            a[p-1] = t;
        }
        sort(a.begin()+p,a.end());//排序
    }
};

60. 第k个排列

给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。

按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:

“123”

“132”

“213”

“231”

“312”

“321”

给定 n 和 k,返回第 k 个排列。

说明:

  1. 给定 n 的范围是 [1, 9]。
  2. 给定 k 的范围是[1,  n!]。

示例 :

输入: n = 3, k = 3

输出: “213”

解法:

康拓编码是本题的标准解法,这里不多赘述了,因为一下子讲不清,这里po一个很详细的题解。

https://leetcode-cn.com/problems/permutation-sequence/solution/di-k-ge-pai-lie-by-leetcode/

代码:

class Solution {
public:
    string getPermutation(int n, int k) {
        vector<int> fac = {0,1,2,6,24,120,720,5040,40320,362880,3628800};
        string res;
        res.clear();
        string s = string("123456789").substr(0,n);
        --k;
        while(k>0){
            int i = k/fac[n-1];
            res += s[i];
            s.erase(s.begin()+i);
            k %= fac[n-1];
            --n;
        }
        return res+s;
    }
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

全网最详细的排列组合系列算法题整理 的相关文章

  • ubuntu安装xgboost,CPU版和GPU版配置

    ubuntu安装xgboost CPU版 第一种方法采用pip安装 xff1a pip install xgboost出现如下报错 xff1a Command 34 python setup py egg info 34 failed wi
  • vmware 下通过Gparted 扩容ubuntu更目录磁盘

    情景 xff1a 因为要扩容的盘挂载在根目录下 xff0c 所以没法直接在ubuntu运行时候用gparted来进行扩容 1 gparted官网下载iso文件 网址 xff1a https sourceforge net projects
  • 批处理窗口自动关闭和暂停办法

    运行bat批处理方式不同 xff0c 处理也不同 一 在资源管理器中 xff0c 双击bat文件方法运行批处理 1 这种方式 xff0c 默认是运行完自动关闭cmd窗口 2 需要运行完批处理 xff0c 然后停留在cmd窗口 xff0c 可
  • 一次Ajax报错:“存储空间不足,无法完成此操作”的解决经验

    连续几天我们收到几位客户的问题工单 xff0c 问题描述都类似 xff0c 都是在做登陆或者交易时报脚本错误 xff0c 交易无法正常执行 我们 远程协助 客户机器时 xff0c 调试发现都是ajax代码出错 xff0c 错误如下 xff1
  • Java异常的另类用法(一)

    异常在我们的代码中是不可避免的 xff0c 有些异常可以忽略 xff0c 多数的异常我们要显式处理 xff08 至少要记录日志 xff0c 以便后面排查问题 xff09 xff0c 这里我们不是要细说异常的处理规范 xff0c 而是使用异常
  • 使用POI在Excel单元格插入符号(Symbol)

    最近看到有人在 技术问答 上提问怎么用java在excel中插入打勾符号 xff1f 我想解决这个问题并不难 我们先打开一个excel文件 xff0c 在里面插入特定符号 xff0c 然后用poi xff08 其他的技术也可以 xff09
  • 系统中定义的一些常见的错误

    ifndef ARM ERRNO H define ARM ERRNO H define EPERM 1 Operation not permitted define ENOENT 2 No such file or directory d
  • Eclipse下C语言的Socket编程(Winsock,gcc)问题总结

    最近心血来潮想从新温习一下C语言 xff08 工作后一直用Java xff0c 其实大学时C语言课程也没好好上 xff0c 正经的代码基本没写过 xff0c 惭愧啊 xff01 xff09 xff0c 找了些小例子 xff0c 修修改改 x
  • 各种哈希函数的java实现

    收集整理 public class HashUtils br private static final int crctab 61 0x00000000 0x77073096 0xee0e612c 0x990951ba br 0x076dc
  • 连接远程linux服务器

    SSH简介 我们在 搭建服务器时通常选择Linux版本 xff0c 如果远程的服务器没有桌面 xff0c mac电脑如何在本地操作远程的服务器呢 方法是很简单的 xff0c mac电脑为我们提供了ssh命令 xff0c 使用这个命令可以快速
  • ArcEngine错误提示

    整理了一下Arcgisengine错误代码 xff0c 希望能帮到大家 错误代码错误描述错误名称HRESULT 0x80040201 Failed to load a resource string icon bitmap etc LOAD
  • 20.android 7.0,8.0,9.0 Settings设置内置选项在一级菜单activity方式

    我的私人博客 xff1a www mrloveqin top 可以查看更多内容 20 Settings内置选项在一级菜单activity方式 在AndroidManifest xml 添加如下代码 span class token oper
  • 21.android 7.0,8.0,9.0 Settings设置内置选项在一级菜单fragment方式

    我的私人博客 xff1a www mrloveqin top 可以查看更多内容 21 Settings内置选项在一级菜单fragment方式 在AndroidManifest xml 添加如下代码 span class token oper
  • 实现手机网页调起原生微信朋友圈分享的工具nativeShare.js

    我们知道现在我们无法直接通过js直接跳转到微信和QQ等软件进行分享 但是现在像UC浏览器和QQ浏览器这样的主流浏览器自带一个分享工具 而他们也有自己定义的js接口 我们通过调用浏览器的接口去调用浏览器的分享 从而实现原生分享功能 是不是很酷
  • 华为机试题[2017.8.23]

    题目 xff1a 给定一个正整数 xff0c 给出消除重复数字以后最大的整数 输入描述 xff1a 正整数 xff0c 注意考虑长整数 输出描述 xff1a 消除重复数字以后的最大整数 下面的好像有问题 xff0c 当输入是4325432时
  • [FAQ202071860]修改uart0输出串口LOG

    QUESTION 修改uart0输出串口LOG ANSWER 1 修改所在工程中的pinmap文件 用来配置UART0 PAD对相应的UART0 控制器 其它芯片也有类似的寄存器用来配置不同的pad对应不同的控制器 请查看相应的芯片spec
  • 使用FileZilla Server如何设置是的ftp同一个账号共享两个文件夹

    在我们使用到FTP来共享文件夹的使用 xff0c 我们通常在自己的ftp服务器上面使用FileZilla Server的软件来共享自己的文件夹 xff0c 我们如果想在同一个账号下面想共享两个或者两个以上文件夹的时候 xff0c 可以把两个
  • 给联想Thinkpad E480 安装了Ubuntu 18.04 Wifi适配器不可用的处理方法

    本人在Thinkpad E480 安装 18 04 后惊奇的发现 xff0c 居然找不到WiFi适配器 xff0c 经过多方搜索是缺少驱动组件 xff0c 查找多个解决方案 xff0c 都或多或少有点问题 xff0c 使用以下操作 xff0
  • 银河麒麟4.0.2配置网络源

    1 编辑sources list文件根据不同版本添加以下网络源地址 sudo vim etc apt sources list 版本网络源地址4 0 2桌面版本 deb http archive kylinos cn kylin KYLIN
  • 在linux终端命令行显示本机IP

    在linux命令行显示本机IP vim etc profile 在最后增加下边语句 xff0c 网卡ens160 根据实际情况设置 有ip addr 命令的情况 span class token assign left variable I

随机推荐

  • 解决apt-get安装中的E: Sub-process /usr/bin/dpkg returned an error code (1)问题

    在用apt get安装软件包的时候遇到E Sub process usr bin dpkg returned an error code 1 问题 xff0c 解决方法如下 cd var lib dpkg sudo mv info info
  • mac 初始化工具

    mac 初始化工具 安装iterm2 xff1a https iterm2 com 安装命令行工具 xcode select install 安装brew bin bash c 34 span class token variable sp
  • odoo 达梦数据库SQL适配

    计算两个时间相差的天数 psql xff1a DATE PART 39 day 39 s date order timestamp s create date timestamp 达梦 xff1a DAYS BETWEEN s date o
  • 使用 rsync 将文件复制到 Docker 容器中的方法

    使用 rsync 将文件复制到 Docker 容器中的方法 确保您的 Docker 容器已安装 rsync xff0c 并定义此别名 xff1a span class token builtin class name alias span
  • 用rm递归递归删除子目录下所有“.”开头的隐藏文件

    find name 34 34 xargs rm 参考网址 xff1a http blog 163 com sweet hard blog static 66656838201162294812840 可以通过管道命令来操作 xff0c 先
  • 多线程压缩与解压缩

    Linux 下用得最普遍的两种压缩文件格式就是 gz 和 bz2 了 xff0c 分别由 gzip 和 bzip2 命令创建 说到压缩文件 xff0c 除了压缩率之外 xff0c 压缩和解压的速度也很关键 xff0c 在创建或解压比较大的压
  • 设置CPU频率和CPU运行核心数

    1 查看当前的CPU信息 span class token function cat span proc cpuinfo ums312 1h10 span class token comment cat proc cpuinfo span
  • 二叉搜索树的第K大节点

    二叉搜索树的第K大节点 第K大的节点就是中序遍历中的第K个节点 span class token keyword class span span class token class name Solution span span class
  • 设置eMMC和DDR的工作频率

    1 MTK 平台查看eMMC和DDR的工作频率 eMMC xff1a adb shell span class token function cat span sys kernel debug mmc0 clock DDR xff1a ad
  • 命令设置Android手机不进入休眠

    在Linux系统中 xff0c wake lock是一直锁机制 xff0c 只要有驱动占用这个锁 xff0c 系统就不会进入深度休眠 获取此锁的方式如下 xff1a adb shell span class token keyword ec
  • Kconfig文件的用途及解析

    1 Kconfig文件的作用 首先 xff0c 内核编译代码的大概过程如下 xff1a 遍历每个源码目录Makefile 61 gt 根据每个目录的Kconfig来配置Makefile xff0c 定制要编译的对象 61 gt 回到顶层目录
  • git format-patch用法

    1 命令介绍 git format patch用来对某次提交生成patch xff0c 方便发送给其他人员进行参考或者同步 2 生成patch用法 基于上几次内容打包 有几个 就会打几个patch xff0c 从最近一次打起 git for
  • SELinux权限添加

    1 avc denied log 如下 span class token number 01 span span class token operator span span class token number 01 span span
  • Android常见指令汇总

    1 查看UID对应的APK 一个UID对应一个APK adb pull data system packages list 2 adb开关机指令 adb span class token function reboot span span
  • WiFi Direct(WiFi P2P)

    Wi Fi Direct技术是Wi Fi产业链向蓝牙技术发起的挑战 xff0c 它试图完全取代蓝牙 Wi Fi Direct是一种点对点连接技术 xff0c 它可以在两台station之间直接建立tcp ip链接 xff0c 并不需要AP的
  • C++经典面试题(九)

    最近看一些面试题 xff0c 觉得如果自己被问到了 xff0c 并不能很利落的回答出来 一是从来没有这个意识 xff0c 二是没有认真的梳理下 下面对这些题做出分析 xff0c 哈 xff01 个人能力有限 xff0c 其中难免有疏漏 xf
  • 我的大学——学习生活总结

    纪念我终将逝去的青春 大一上學期 專業 1 C語言K amp R amp amp 習題 2 C語言經典習題 3 C語言趣味習題 4 C陷阱与缺陷 5 彙編語言 6 C 43 43 程序設計 7 C 程序設計
  • 基于Python的开源人脸识别库:离线识别率高达99.38%——新开源的用了一下感受一下

    该项目是要构建一款免费 开源 实时 离线的网络 app xff0c 支持组织者使用人脸识别技术或二维码识别所有受邀人员 有了世界上最简单的人脸识别库 xff0c 使用 Python 或命令行 xff0c 即可识别和控制人脸 该库使用 dli
  • 5G智慧医疗十大应用场景,你知道多少?

    来源 xff1a 北京物联网智能技术应用协会 都说5G会改变千行百业 xff0c 其中 xff0c 5G医疗健康就是5G技术在医疗健康行业的一个重要应用领域 随着 5G 正式商用的到来以及与大数据 互联网 43 人工智能 区块链等前沿技术的
  • 全网最详细的排列组合系列算法题整理

    写在前面 LeetCode上面排列组合系列几乎所有题目放在一起整理了一下 面试题 08 07 无重复字符串的排列组合 无重复字符串的排列组合 编写一种方法 xff0c 计算某字符串的所有排列组合 xff0c 字符串每个字符均不相同 示例 输