LeetCode高频题:请你打印int数字x的所有全排列,x只包含且必须包含1

编程入门 行业动态 更新时间:2024-10-22 13:31:51

LeetCode高频题:<a href=https://www.elefans.com/category/jswz/34/1749932.html style=请你打印int数字x的所有全排列,x只包含且必须包含1"/>

LeetCode高频题:请你打印int数字x的所有全排列,x只包含且必须包含1

LeetCode高频题:请你打印int数字x的所有全排列,x只包含且必须包含1-9的每一个数字

提示:本题是系列LeetCode的150道高频题,你未来遇到的互联网大厂的笔试和面试考题,基本都是从这上面改编而来的题目
互联网大厂们在公司养了一大批ACM竞赛的大佬们,吃完饭就是设计考题,然后去考应聘人员,你要做的就是学基础树结构与算法,然后打通任督二脉,以应对波云诡谲的大厂笔试面试题!
你要是不扎实学习数据结构与算法,好好动手手撕代码,锻炼解题能力,你可能会在笔试面试过程中,连题目都看不懂!比如华为,字节啥的,足够让你读不懂题


文章目录

  • LeetCode高频题:请你打印int数字x的所有全排列,x只包含且必须包含1-9的每一个数字
    • @[TOC](文章目录)
  • 题目
  • 一、审题
  • 二、解题
  • 总结

题目

请你打印int数字x的所有全排列,x只包含且必须包含1-9的每一个数字
x只包含1-9
而且x必须包含1-9
请你输出x的所有排列情况


一、审题

示例:
123456789
213456789
321456789
423156789
523416789
623451789
723456189
823456719
923456781

……
总之,只包含1-9的每个数字

各种情况
挺多的


二、解题

其实从示例中你也能看出来的
不就是高位那个1跟所有低位分别交换一次吗????

int类型的数字,如何快速交换,我们讲过的!
【1】LeetCode高频题:如何不用int转字符数组,实现int类型数字x的第L位和R位数字交换

int类型的数字x将L和R位置交换,是这么干的

    //就把x的L=7位置和R=2位置的俩数字交换了public static final int[] arr = {1,10,100,1000,10000,100000,1000000,10000000,100000000};//准备好常量arri表示1后面跟i个0public static int swap(int x, int L, int R){//将x的L和R处数字交换//首先把L和R处数字提取出来,就可以利用加减法换L和Rint numL = x / arr[L] % 10;int numR = x / arr[R] % 10;//L这里是x-([L]-[R])*10的L次方=a//R这里是a+([L]-[R])*10的R次方int a = x - (numL - numR) * arr[L];//完成L变Rint b = (numL - numR) * arr[R];//完成R变Lreturn a + b;//最终L和R调换,以后千万别把int转char[],这样很费时间的}

普通的数组是这么交换的:

        public void swap(int[] arr, int i, int j){int tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}

显然数组更方便,但是int数字的交换不能转化为数组,否是速度很慢!

而当初我们也求过字符数组,或者int数组的全排列,跟现在要求的int数字的全排列,一模一样,我也讲过的,无非就是让目标index位置
跟index–N-1所有的位置都交换一波,剩下的当一个整体,继续递归玩

【2】LeetCode高频题46. 全排列

数组类型的arr,全排列用数组交换办,很简单

//复习:依次从arr的i位置决定谁做排头,然后去i+1继续做决定public void f(int[] arr, int i, List<List<Integer>> ans){//直到i越界,收集此刻的arrif (i == arr.length){//每次都要把arr转ListList<Integer> cur = new ArrayList<>();for(Integer x : arr) cur.add(x);//全部加入ans.add(cur);//作为一个排列组合结果,放入ans}else {//没有越界,决定让i跟谁换?//来此来到i,让i和j=i--N-1交换一次,剩下的数字继续递归i+1位置,但是干的事情,又是这个递归for (int j = i; j < arr.length; j++) {swap(arr, i, j);//不断往下,基本就让所有的数字做了开头,然后还考虑别的数字依次做了开头的情况//就是排列组合,每个数字做一次开头,剩下的数字继续缩短长度,// 又玩一次每个数字做一次开头,这样枚举下去f(arr, i + 1, ans);//返回上一层,你上次怎么交换的,给我换回来,恢复现场,// 我方便在i-1层继续让i和别的j位置交换,让另外的j来做排头swap(arr, j, i);}}}//主函数,就从i=0开始调用递归public List<List<Integer>> permuteReview(int[] nums) {List<List<Integer>> ans = new ArrayList<>();//从i=0开始决定谁做排头,收集一波答案f(nums, 0, ans);return ans;}

【1】【2】俩文章综合就是咱们要办的事情:只不过int交换和数组交换不是一个做法,思想一样
目的就是让index处,从1–9固定做一次派头之后,剩下的数字又从index+1开始当新的数字x,
去递归固定index处的数字,,从1–9固定做一次派头之后,剩下的数字又从index+1开始当新的数字x……

我想想需要恢复现场吗?
这个好像不用,你f递归完之后,目前的x,它不是数组,x就是x本身,你怎么玩都是没关系的

我定义递归函数f(x,index)
来到x的index位,先把x固定一个数字做排头(1–9都要尝试排头),剩下的x从index+1位置往后去继续递归

撸代码:

    //我定义递归函数**f(x,index)**//来到x的index位,先把x固定一个数字做排头(1--9都要尝试排头),剩下的x从index+1位置往后去继续递归public static void f(int x, int index){if (index == -1){System.out.println(x);//index来到-1处,说明8--0位置的排头决定好了}else {//来到index,让谁来做排头?index--N-1位置每个数字轮流做,不是数组,不需要恢复现场for (int j = index; j >= 0; j--) {//从高位L跟低位R=j处换int next = swap(x, index, j);//index和j换数字f(next, index - 1);//然后去index=1处玩剩下的数字——不需要恢复现场,x没有动过//待会f结束,x依然是x,然j轮流做排头就行了}}}

非常容易的,x之所有不需要恢复现场,是因为咱们next操作的时候,没有动过x
所以f递归出来之后啊,x还是x没动,该交换谁跟谁交换即可
每次index–,咱们从高位8—0位去交换,不是index+1哦

测试一把:

    public static void test(){int x = 123456789;
//        System.out.println(swap(x, 7, 2));f(x, 8);//8--0这9个数字}public static void main(String[] args) {test();}

速度非常快,就枚举完了,所以我只打印最后几个数字
就是9做了排头,然后枚举完成

912345876
912345867
912345687
912345678

太多了

复杂度多少呢???
9个数字全排列,1个位置9种情况,剩下的就是8种情况了,……
实际上就是9!=362880次交换操作
才36万次枚举
这远远小于10的8次方【java要求的4s内数据运行次数】

就是这么暴力地枚举,速度也足够快!!!


总结

提示:重要经验:

1)和之前讲过的全排列一样,就是让arr【x】的index和index–N-1位置交换,每一个位置做一次排头即可
2)只不过arr的交换很容易,但是int数字的x交换稍微做个除法取模加减法转换一下,速度快,千万不能把int类型x转化为字符数组去交换,再连乘去转数字,这样速度极其慢的
3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。

更多推荐

LeetCode高频题:请你打印int数字x的所有全排列,x只包含且必须包含1

本文发布于:2024-02-06 15:23:06,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1749804.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:请你   排列   数字   LeetCode   int

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!