思路分析 这道题是一道非常典型的 BFS 题目, BFS 所面临的最大问题是判断重复。显然,如果每次判断重复都扫描一次队列,搜索的效率会非常低,会提高一个指数级,所以一般宽度搜索的判断重复都是运用数组来实现的。那么数组下标就需要用一个 Hash 函数来计算。因此,设计 Hash 函数就显得非常重要。 本题 Hash 函数的设计:我们很容易想到将 8 个数字按顺时针顺序组合成 8 进制(每个数字都减 1 )的 8 位基数。但是,这里最大的八进制数 76543210 ,转换成十进制数就是 16434824 ,也就是说要开大小为 16434824 的数组,如果题目强制空间限制,那么,数组下标会越界。 这里我们引入康托展开,即将一个排列对应成它在全排列中的序数,这样就不会 MLE 了。 如 {1,2,3,4,···,n } 表示 1,2,3,4,···,n 的一个排列,如 {1,2,3} 按从小到大排序,一共有6个: 1 2 3,1 3 2,2 1 3,2 3 1,3 1 2,3 2 1,分别代表数字 1,2,3,4,5,6,也就是把 10 进制数与一个排列对应起来。它们之间的对应关系可有康托展开来找到。如果想知道 321 时 {1,2,3} 中第几大的数,可以这样考虑:第一位是 3 ,当第一位的数字小于 3 时,对应的排列数都小于 321,如 123,213,则小于 3 的数有 1,2,所以有 2×2! 个;再看小于第二位的数 2 ,小于 2 的数只有一个就是 1,所以有 1×1!=1。因此小于 321 的 {1,2,3} 排列数共有 2×2!+1×1!=5 个,所以 321 是第六大的数。 再如 1324 是 {1,2,3,4} 排列数中第几大的数? 第一位数字是 1,小于 1 的数没有,是 0 个,即 0×3! ;第二位数字是 3,小于 3 的数有 1,2,但 1 已经在第一...