我是靠谱客的博主 满意大象,最近开发中收集的这篇文章主要介绍回溯法数字全排列_面试超级爱问的全排列!!!,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

我准备了 1000 本电子书和计算机各领域高清思维导图 100 张,关注后回复【资源】,即可获取!更可回复【内推】加入 BAT 内推群!

c76d5a7a27cccbae07284243e585652d.gif

今天为大家分享如何用算法来求全排列!话不多说,直接看题!

01、全排列概念

什么是全排列?从 n 个不同元素中任取 m(m≤n)个元素,按照一定的顺序排列起来,叫做从 n 个不同元素中取出 m 个元素的一个排列。当 m=n 时所有的排列情况叫全排列。

比如 [1,2,3] 全排列共有 6 种:

891b0627646d799bb545243394b4f1ae.png

02、全排列题目

然后把上面的全排列稍微改改,就变成了一道算法题。。。

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

示例:

输入: [1,2,3]

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

03、题解分析

这种由基础数学知识改编而成的题目,在面试时还是很受欢迎的。因为作为面试官,可以用这种题目,来显示自己的博学。(谬论)

假如我们不是做算法题,而是做数学题。我们会一个位置一个位置的来考虑,先写出以1开头的排列,再写出以2开头的排列,最后写出以3开头的排列。

183147281a28d521e372ec77035ac98b.png

这种思路是不是很像深度优先(DFS)的求解过程呢?

1、我们先选择 1,然后为 1 的第二位选择 2,此时 1 的 第三位只能选择 3。

13fd86604d8aafe43cc00c57eeccd51c.png

2、然后完成了上面的步骤,我们需要回退到 1,因为只有 1 这里还存在别的选择 1-3,然后填写 1-3 后,只有 1-3-2 一种选择。

a0a074498dff1e1992618d76cb8fdd18.png

3、此时我们需要从 1-3-2,回退到 1-3,再回退到 1,再回退到 根节点,然后重新选择 2。

8bef81a26e19050ec71deaba0c0af143.png

4、后面的流程与前面相似,我就不一步步的描述了。

96a9871992ce3c051a8a7dffb3d32022.png

当然,如果不省略其回溯过程,就是下面这个样子:

上面分析是分析完了,但是仍然不妨碍你继续懵逼。。。“题目中不是给我的是一个数组吗?作为一个合格的算法小白,我特么根本就不知道 DFS 在这里面咋用啊!!”本来想扔完代码就走,想了想还是决定讲一下。

我们把代码先丢出来(注意,这个代码不是最优的,这样写只是易于大家理解。比如我们还可以通过置换的方式来进行优化,又或者其他的优化方法。但是都大同小异,核心是回溯的过程):

//JAVA 
class Solution { 
    List> ans = new ArrayList<>(); public List> permute(int[] nums) { 
        dfs(nums, new ArrayList<>()); return ans; 
    }private void dfs(int[] nums, List tmp) {
        System.out.println(Arrays.toString(nums) + "," + tmp);if (tmp.size() == nums.length) {
            ans.add(new ArrayList<>(tmp));
        } else {for (int num : nums) {if (!tmp.contains(num)) {
                    tmp.add(num);
                    dfs(nums, tmp);
                    tmp.remove(tmp.size() - 1);
                }
            }
        }
    }
}

假若 nums 为 [1,2,3],会有下面的输出:

1517e378e4f1f1bc934025339f3fe310.png

其实这个代码还是很容易理解的,他干了个啥事?就是当我们按顺序去枚举每一位时,我们要把已经选择过的数字排除掉(第16行代码),比如我们上面选择三个数字:

  • 在枚举第一位的时候,就有三种情况
  • 在枚举第二位的时候,就只有两种情况(前面已经出现的一个数字不可以再出现)
  • 在枚举第三位的时候,就只有一种情况(前面已经出现的两个数字不可以再出现)

整个代码其实就干了这么一件事!而 第12行 的代码,其实就是说当枚举到最后一位的时候,这个就是我们要的排列结果,所以我们要放入到全排列结果集中。

那这里还有一个很重要的代码,其实是 第19行,这一步其实是干啥!说白了就是在回到上一位时,我们要就把上一次的选择结果撤销掉。不然如果你之前选过了,后面不就不能继续用了么。

04、总结

回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

这是最简单的一道全排列题目,注意我在上面的题解中,并没有引入什么状态、路径、选择列表、结束条件之类的专业术语,甚至我连回溯的概念都没有提及。

之所以这样讲,我是希望咱可以从最简单的人类思考出发,而不是去套用一些框架之类的东东。。。。当然,至于更多的概念和回溯框架的东西,我会在后面更为复杂的题目中为大家引入。

2ae70cf6bcdc8074636619509d86208e.png

我把一千本开源电子书,以及我写的 140 多篇算法图解,进行了汇总。下方扫码回复【资源】就可以全部下载 !!!

f4d0dd6a8677779cec7d617513bc4a91.png

内容展示:

617793e8dca3850da9a9a04862524a4e.png

9ba5463716a4d232be3949e9e6734f44.png 今日论点:

程序员是一个吃青春饭的工作吗?

d98acbf9eed3db64dbf6b703695ed425.png 互联网公司盛行的加班文化,对于大龄的程序员们,且不说身体吃不吃不得消、陪家人、照顾父母、孩子、家庭琐事也让他们很难像刚毕业的年轻人一样有足够的精力全身心的投入在工作中。 其次大龄技术人员的学习能力和好奇心会被认为不如年轻人,人的精力毕竟是有限的,当你要把注意力放在家庭上,则意味着你将很难全身心关注工作。 it行业新的技术时刻在发生,一旦与这个时代脱轨了、语言落后了、当下所用的技术逐渐被淘汰了,则也将意味着很难继续适应和满足当下工作要求。 企业希望引进新鲜的血液为公司带来新的文化、知识、技能,保证自身的市场竞争力,而一个坑一个萝卜,则必将意味着老将终究是要逐渐淡出、退居幕后。

大家怎么看呢?评论区留下你的想法吧!

最后

以上就是满意大象为你收集整理的回溯法数字全排列_面试超级爱问的全排列!!!的全部内容,希望文章能够帮你解决回溯法数字全排列_面试超级爱问的全排列!!!所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(105)

评论列表共有 0 条评论

立即
投稿
返回
顶部