全排列 Ⅱ--回溯算法

2023-11-09

LeetCode

全排列

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

示例:

输入: [1,1,2]
输出:
[
    [1,1,2],
    [1,2,1],
    [2,1,1]
]

解法:回溯法

解题思路:思路很简单,因为要全排列,所以每一个数字都可能选择,即选择区间为[0,nums.length], 但是一个数字只能被选择一次,所以我们需要定义一个boolean[] used数组,长度为nums.length,又因为不能有重复的,所以一个数字的选择不能相同,我们通过这一行代码来剪枝

if(i>0 && nums[i]==nums[i-1] && !used[i-1])
    continue;

当当前数字和上一个数字相同时,且上一个数字没有被使用,我们就进行剪枝

因此我们需要对数组进行排序

完整代码:

class Solution {
    public List<List<Integer>> permuteUnique(int[] nums)
    {
        List<List<Integer>> res= new ArrayList<List<Integer>>();
        if(nums.length == 0)
            return res;
        List<Integer> sub = new ArrayList<Integer>();
        boolean[] used = new boolean[nums.length];
        Arrays.sort(nums);
        dfs(used, nums, 0, res, sub);
        return res;
    }
    public void dfs(boolean[] used, int[] nums, int len, List<List<Integer>> res, List<Integer> sub)
    {
        if(len==nums.length) //用len来表示全排列子集的长度
        {
            res.add(new ArrayList<>(sub));
            return;
        }
        for(int i=0; i<nums.length; i++) //从nums中取数字
        {
            if(i>0 && nums[i]==nums[i-1] && !used[i-1])//剪枝
                continue;
            if(!used[i])
            {
                used[i]=true;//置为被使用
                sub.add(nums[i]);
                dfs(used, nums, len+1, res, sub);
                sub.remove(len);//删除
                used[i]=false;//回溯
            }
            else
                continue;
        }
    }
}

解法2:交换法,不用used数组

解题思路:

以[1, 2, 3]为例子,按照下面的树回溯出整个全排列:

[|1, 2, 3] -> [1|, 2, 3]

[1|, 2, 3] -> [1, 2|, 3], [2, 1|, 3]

[1, 2|, 3] -> [1, 2, 3|], [3, 2, 1|], [1, 3, 2|]

[2, 1|, 3] -> [2, 1, 3|], [3, 1, 2|], [2, 3, 1|]

ps:以[1, 2|, 3] -> [1, 2, 3|], [3, 2, 1|], [1, 3, 2|]为例,’|'往后移动一位,得到[1, 2, 3|];[1, 2, 3|]中的3和1位置交换,得到[3, 2, 1|];[1, 2, 3|]中的3和2交换位置,得到[1, 3, 2|]。
按照这个思路,可以解决问题

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

public class Solution {
    public List<List<Integer>> permuteUnique(int[] nums)
    {
        List<List<Integer>> res= new ArrayList<List<Integer>>();
        if(nums.length == 0)
            return res;
        int current_len = 0;
        Arrays.sort(nums);
        backtrack(res,current_len,nums);
        return res;
    }
    public void swap(int[] nums, int a, int b)
    {
        int temp = nums[a];
        nums[a] = nums[b];
        nums[b] = temp;
    }
    public void backtrack(List<List<Integer>> res, int current_len, int[] nums)
    {
        if(current_len == nums.length)
        {
            List<Integer> numsl = new ArrayList<Integer>();
            for(int i=0; i<nums.length; i++)
                numsl.add(nums[i]);	
            res.add(numsl);
            return;
        }
        current_len++;
        backtrack(res,current_len,nums);
        current_len--;
        for(int i=0; i<current_len; i++)
        {
            if(nums[i] == nums[current_len])
                break;
            swap(nums,i,current_len);
            current_len++;
            backtrack(res,current_len,nums);
            current_len--;
            swap(nums,i,current_len);
        }
    }
}

解法来源于

作者:tai-yang-tian

链接:https://leetcode-cn.com/problems/permutations-ii/solution/shuang-bai-si-lu-chao-ji-jian-ji-by-tai-yang-tian/
来源:力扣(LeetCode)

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

心得体会

感觉回溯算法还是比较简单的,现在中等难度的题已经可以比较轻松的解决了,下面会做一些困难难度的题,毕竟不能老是呆在舒适区,这样也进步不了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

全排列 Ⅱ--回溯算法 的相关文章

随机推荐

  • bukku ctf(刷题2)

    bugku ctf 抄错的字符 简单取证1 这是一张单纯的图片 计算器 GET POST 矛盾 alert 你必须让他停下 signin Easy Re 游戏过关 Easy vb 树木的小秘密 Timer 阿里CTF 抄错的字符 Crypt
  • Handler进阶之sendMessage原理探索

    Handler进阶之sendMessage 本文主要进一步的探索Handler 主要介绍下Handler是如何发送消息的 用过Handler的想必对以下几个方法都不会陌生 sendMessage Message msg 立刻发送消息 sen
  • Jdk下载和安装

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 下载JDK 二 安装JDK 三 配置环境 四 检验安装 前言 学习java第一步 写java文件都需要配置java环境 提示 以下是本篇文章正文内容 下面
  • 嵌入式-术语解释(不定时更新)

    饱和操作 饱和运算 饱和运算 就是当运算结果大于一个上限或小于一个下限时 结果就等于上限或是下限 饱和加法 a b c 当计算结果大于c可表示的最大值或者小于c可表示的最小值时 计算结果取值为这个最大值或最小值 非饱和加法 a b c 如果
  • LINQ的技术演进

    以一个简单的例子来说明 var developersUsingCSharp from d in developers where d Language C select d Name 1 提供对IEnumerable
  • 基于MATLAB编程的PCA改进GA-BP回归分析

    目录 BP神经网络的原理 BP神经网络的定义 BP神经网络的基本结构 BP神经网络的神经元 BP神经网络的激活函数 BP神经网络的传递函数 PCA的定义 遗传算法的原理及步骤 基于遗传算法改进BP神经网络的二分类 代码 效果图 结果分析 展
  • Java 学习历程

    最近论坛上看到好几个朋友都在问 如何学习 Java的问题 我已经学习了J2SE 怎么样才能转向J2EE 我看完了Thinking in Java 可以学习J2EE了么 于是就有了写这篇文章的想法 希望能帮助初学者少走一些弯路 也算是对自己几
  • Java中参数的传递机制,究竟是值传递还是引用传递?

    先说结论 Java语言中 本质上只有值传递 没有引用传递 废话不说 咱们直接来看例子 public class Demo public static void main String args int i 10 testInt i Syst
  • 您的嵌入式开发团队的静态代码分析工具是什么? 这份指南你一定需要

    所有的静态分析工具从50 000英尺高空看去往往都是一样的 当计划部署静态分析时 重要的是选择一个适合组织需求的解决方案 并能随着未来的需求而增长 一个工具应该具备的特点和能力可以分成两组 第一组是常见的 预期的技术功能 如支持的语言 ID
  • 波形失真总结

    失真是输入信号与输出信号在幅度比例关系 相位关系及波形形状产生变化的现象 音频功放的失真分为电失真和声失真两大类 电失真是由电路引起的 声失真是由还音器件扬声器引起的 电失真的类型有 谐波失真 互调失真 瞬态失真 声失真主要是交流接口失真
  • QApplication、QGuiApplication和QCoreApplication三者的区别与联系

    为什么80 的码农都做不了架构师 gt gt gt 从继承关系看 QApplication父类是QGuiApplication QGuiApplication父类是QCoreApplication 开发的应用无图像界面 就使用QCoreAp
  • Ant Trip 【HDU - 3018】【欧拉通路一笔画问题】

    题目链接 欧拉通路与欧拉回路不同 欧拉通路其实不强制要求走回 也就是不要求最后从哪开始 然后再回到哪 这道题 是问的我们需要走几次一笔画 那么 很显然 考虑入度出度以及连通性 在同一个联通块中 我们可以拆分成如下几种可能 形成闭环 无奇数度
  • REST API 最佳入门指南

    点击上方 程序员大咖 选择 置顶公众号 关键时刻 第一时间送达 如果你看到这里 你以前可能听说过API 和REST 然后你就会想 这些都是什么东西 也许你已经了解过一些这方面的知识 但却不知道从何入手 在这个教程中 我将会诠释REST的基础
  • create umi创建项目

    1 环境准备 安装node node确保它是 8 10 或更高版本 node v v14 17 0 安装yarn 推荐用于yarn管理 npm 依赖 npm install g yarn gt yarn 1 22 10 preinstall
  • keepalived工作原理和配置说明

    keepalived是什么 keepalived是集群管理中保证集群高可用的一个服务软件 其功能类似于heartbeat 用来防止单点故障 keepalived工作原理 keepalived是以VRRP协议为实现基础的 VRRP全称Virt
  • 斗智斗勇 -- 谷歌浏览器的主页被篡改

    不知道从什么时候开始 每次我打开谷歌浏览器 都会跳出2345网址导航 界面花里胡哨的 今天实在是忍无可忍了 就对他动手了 百度了半天 又是禁服务 又是删注册表的 一直然并软 最后实在没办法 只能装个电脑管家试试了 解决完问题再卸载吧 安装好
  • 在rdesktop 远程时报如下错误Autoselecting keyboard map ‘en-us‘ from localeCore(warning): Certificate received

    在rdesktop 时报如下错误 Autoselecting keyboard map en us from locale Core warning Certificate received from server is NOT trust
  • IT项目管理第七次作业

    完成作业1 3的要求 使用 project 或其他项目管理工具 1 假设 每项工作的单位小时成本数如下表 项目经理单位小时成本为100 项目团队成员单位小时成本为60 WBS条目 小时数 单位小时成本 美元 子层总合 美元 WBS第二层的总
  • java 内存溢出 扩大jvm内存

    随手小记 今天下午遇到一个问题 java lang OutOfMemoryError Java heap space 内存溢出问题 遇到这个问题一般有两个解决方式 第一种 修改代码程序 代码中存在大量未被释放的对象引用 或者gc 机制没有来
  • 全排列 Ⅱ--回溯算法

    LeetCode 全排列 给定一个可包含重复数字的序列 返回所有不重复的全排列 示例 输入 1 1 2 输出 1 1 2 1 2 1 2 1 1 解法 回溯法 解题思路 思路很简单 因为要全排列 所以每一个数字都可能选择 即选择区间为 0