详讲全排列算法,及解决数字搭积木问题
如果你是做这道题不会,那么你可以看这道题的解题思路,如果你是不太理解全排列算法,那么你可以通过这个题来理解。
题目描述:
小明最近喜欢搭数字积木。一共有10块积木,每个积木上有一个数字,0~9。
搭积木规则:
每个积木放到其它两个积木的上面,并且一定比下面的两个积木数字小。
最后搭成4层的金字塔形,必须用完所有的积木。
下面是两种合格的搭法:
请你计算这样的搭法一共有多少种?
分析
一共有10个数字,要我们把所有可行的排列方式都求出来,一时没什么思路,索性就全排列了,把所有排列的情况都求出来,然后在把每种情况都判断一下,是不是就可以得到答案了。
所以全排列怎么写成了第一大问题了。
全排列
对于这个问题来说,我们把金字塔当成一个int数组,那么就为 全排列这个数组{0,1,2,3,4,5,6,7,8,9}。
太长了,想不明白呀,所以来看比较少的呗。
对于{0,1}全排列,就是把0抽出来,1做全排列,再把1抽出来,0做全排列,对于{0,1,2},就是:
- 把0抽出来,把1,2做全排列,
- 把1抽出来,把0,2做全排列,
- 把2抽出来,把0,1做全排列。
- 接下来那不就和上面那个{0,1}一样了吗?
这是不是个递归呢?很明显吧。的确是。
那好我们定义一个方法,这个方法的作用是,把list数组全排列,而参数curr表示当前抽出来的那个数,就像上面例子提到的0一样。
提出来了之后呢,是不是要把curr交换了,这样就可以把所有在这个位置上的所有情况列出来了,所以使用一个for循环,来交换curr和后面剩余数组的数(就是上面例子的1,2,3步骤)。
所以紧接着定义一个方法,交换两数swap(list,curr,j);
,当然你也可以把这个方法直接写到这个函数里面,但是毕竟不美观,不实用。
重点来了:回溯!!!
从这张图中,所谓回溯就是要回到上一没有操作过的状态,再去考虑别的情况。就下面这个A,B,C他需要回到上一次抽数出来之前的状态。这样他才能去抽另外一个数,全排列下一种情况。所以我们再写一遍swap(list,curr,j);
,把它原来的状态恢复就行了嘛。
问题分析到这了,我们的代码基本上就可以出来了,所以看下代码,如果看不懂在回到我的分析,相信你一定能看懂。
public class Test2 {static int sum ;public static void main(String[] args) {int list[] = {0,1,2,3,4,5,6,7,8,9};allSort(list,0);System.out.println(sum);}//代表将第a[m]和a[n]相交换public static void swap(int a[],int m ,int n){int temp = a[m];a[m] = a[n];a[n] = temp;}//调用全排列数组list,curr代表当前放在第一个的为第几个数字,比如开始就为数组第0个数字public static void allSort(int list[],int curr ){//如果当前数组的索引等于数组的长了,就将方法加1if (curr == list.length-1){check(list);}else {for (int j = curr; j < list.length; j++){swap(list,curr,j);//交换当前抽出来那个数allSort(list,curr+1);swap(list,curr,j);//回溯}}}public static void check(int list[]){if (list[1] < list[0]) return;if (list[2] < list[0]) return;if (list[3] < list[1]) return;if (list[4] < list[1]) return;if (list[4] < list[2]) return;if (list[5] < list[2]) return;if (list[6] < list[3]) return;if (list[7] < list[3]) return;if (list[7] < list[4]) return;if (list[8] < list[4]) return;if (list[8] < list[5]) return;if (list[9] < list[5]) return;sum++;}}
其实这个全排列都可以当成一个模板了,但是还是推荐大家一定要手敲,自己写代码,写出来了,才是自己的东西。
图片参考:https://blog.csdn.net/Strom72/article/details/80738818
详讲全排列算法,及解决数字搭积木问题相关推荐
- 数组积木问题 c语言,全排列算法及解决数字搭积木问题
如果你是做这道题不会,那么你可以看这道题的解题思路,如果你是不太理解全排列算法,那么你可以通过这个题来理解. 题目描述: 小明最近喜欢搭数字积木.一共有10块积木,每个积木上有一个数字,0~9. 搭积 ...
- 算法AK说 又是递归?! 这样讲全排列算法,应该明白了!
写在前面:大家好K.首先为你点进这篇有趣的文章点赞
- 全排列算法(无重复数字全排列/有重复数字全排列)/ 组合算法/ 求子集算法
写在前面 全排列 1 无重复数字全排列 1.1 紫书版本 1.2 回溯法 2 有重复数字全排列 复盘易错点(可跳过) 写在前面 很久很久以前就想写的一篇博客,因为懒一直没开工,但是学习全排列算法算是我 ...
- php数字全排列,全排列算法 - php 实现
今天遇到了一个全排列的算法题目,回顾下算法实现. 全排列实现思路: 1. 当需要全排列的元素个数 N = 1 ,则全排列只有它; 2. 当需要全排列的元素个数 N > 1 ,则全排列为 每一个元 ...
- 区块链技术用解决拜占庭将军问题_两军问题_拜占庭将军问题详解图解算法
两军问题 我们来看一下好处理器的情况,但通信线路有问题.这就是所谓的两军问题,可以概括如下: A,B 两军师协同攻击敌军C, A和B在物理上是分开的,并使用信使进行通信. A向B发送一个消息" ...
- [通用技术]在不同语言中用协程实现全排列算法(C++/Lua/Python/C#)
我这里实现全排列的基本算法如下(C++): 1 #include <algorithm> 2 #include <iostream> 3 #include <vector ...
- 详解rsync算法--如何减少同步文件时的网络传输量
详解rsync算法--如何减少同步文件时的网络传输量 先看下图中的场景,客户端A和B,以及服务器server都保存了同一个文件,最初,A.B和server上的文件内容都是相同的(记为File.1).某 ...
- 详解校招算法与数据结构
算法与数据结构(java)版 一,数据结构 1,数组和链表 (1)数组 数组是最常见的一种数据结构,它是相同类型的用一个标识符封装到一起的基本类型数据序列或者对象序列.数组使用一个统一的数组名和不同的 ...
- 详解线性回归算法的纯Python实现
↑↑↑关注后"星标"简说Python人人都可以简单入门Python.爬虫.数据分析 简说Python推荐 来源|天池大数据科研平台作者|黄佳 零基础学机器学习--一文详解线性回归算 ...
最新文章
- 【分块答案】【最小割】bzoj1532 [POI2005]Kos-Dicing
- enkey java_近期的Java项目(前端)
- IT与业务之间的鸿沟根源
- 关于SimpleDateFormat时间格式化线程安全问题
- python程序设计第一章答案_Python《学习手册:第一章-习题》
- c语言常用库函数使用方法,c语言常用库函数使用方法及用途
- 不用图片而用css3实现一些阴影特效
- 听说你不会用datetime处理时间?
- SharePoint 2010整体进行验证
- achartengine画出动态折线图
- NYOJ----1591----模拟+map
- 最新免费可使用在线音乐网站+多解析源码
- 备查:ASCII码表
- 软件相貌测试准确吗,测另一半的相貌超准软件 提前了解对象的外貌
- 程序员如何成为别人的男朋友
- 利用photoshopcs6将gif格式图片变为背景透明
- SpringBoot 集成 ES 7.6.2 并对字段进行中文和拼音分词处理
- CAGD(计算机辅助几何设计)大作业
- python tk窗口 选择 销毁_Python tkinter - 删除其他窗口 - 已调用tk.withdraw()
- Intent Service 和Service的区别
热门文章
- 三层交换机与单臂路由的优缺点
- PLUG AND PLAY LANGUAGE MODELS: A SIMPLE APPROACH TO CONTROL LEDTEXT(PPLM):代码深入理解(二)—PPLM_Discrim
- 【Redis笔记】一起学习Redis | 如何利用Redis实现一个分布式锁?
- 做自己喜欢的事情,是假的,改变世界也是假的
- TS在vue中的应用
- MicroStrain 3DM-GX3-25 ROS 开发
- 联想服务器SR650升级网卡固件微码
- gitee注册新用户收不到验证码, 不管是手机还是邮箱都收不到验证码解决方案
- 揭秘Microsoft Windows LDM
- “画仓鼠” 大赛,正式回归了!