最近在学习STL源码,买了两本书:侯捷大大的《STL源码剖析》和他翻译的《深入探索C++对象模型》。并且实验室的工作挺忙,因此没时间刷题了。前天模拟了一场虚拟竞赛,碰到了这道题。当时觉得挺有意思的,没有写,只是想了个思路。昨天晚上我才做好这道题。
给你两个整数 n 和 start。你的任务是返回任意 (0,1,2,,...,2^n-1) 的排列 p,并且满足:
p[0] = startp[i] 和 p[i+1] 的二进制表示形式只有一位不同p[0] 和 p[2^n -1] 的二进制表示形式也只有一位不同示例 1:
输入:n = 2, start = 3 输出:[3,2,0,1] 解释:这个排列的二进制表示是 (11,10,00,01) 所有的相邻元素都有一位是不同的,另一个有效的排列是 [3,1,0,2]示例 2:
输出:n = 3, start = 2 输出:[2,6,7,5,4,0,1,3] 解释:这个排列的二进制表示是 (010,110,111,101,100,000,001,011)提示:
1 <= n <= 16 0 <= start < 2^n我当时想出来的思路比较简单。对于这道题来说,其实题目要求的输出只是一个格雷码。例如输入n = 3的时候,格雷码为000, 001, 011, 010, 110, 111, 101, 100。格雷码的生成算法也非常直观:
∀ n − b i t B i n a r y N u m b e r B B = B 1 B 2 B 3 . . . B n ∃ n − b i t B i n a r y G r a y C o d e G G n = B n ⊕ B n + 1 G = G 1 G 2 G 3 . . . G n \forall \ n-bit \ Binary \ Number B \\ \ \ \ B = B_1B_2B_3...B_n \\ \exists\ n-bit \ Binary\ Gray\ Code\ G \\ \ \ \ G_n = B_n\oplus B_{n+1} \\ \ \ \ G = G_1G_2G_3...G_n ∀ n−bit Binary NumberB B=B1B2B3...Bn∃ n−bit Binary Gray Code G Gn=Bn⊕Bn+1 G=G1G2G3...Gn
既然算法如此直观,那么其实下面的思路就非常简单了:
首先,根据输入n,我们生成一个从小到大的序列 a。对a中的每一个元素使用上面的算法求出格雷码,生成一个新的序列b。以a[start]为起点,循环输出整个序列b。没啥好总结的。我在leetcode的题解里看到有其他的解法,但是实际上也都差不多,多以就不放出来了。
