开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 23 天,点击查看活动详情
刷题的日常-2023年2月25号
一天一题,保持脑子清爽
循环码排列
来自leetcode的 1238 题,题意如下:
给你两个整数 n 和 start。你的任务是返回任意 (0,1,2,,...,2^n-1) 的排列 p,并且满足:
- p[0] = start
- p[i] 和 p[i+1] 的二进制表示形式只有一位不同
- p[0] 和 p[2^n - 1] 的二进制表示形式也只有一位不同
示例如下
输入:n = 2, start = 3
输出:[3,2,0,1]
解释:这个排列的二进制表示是 (11,10,00,01)
所有的相邻元素都有一位是不同的,另一个有效的排列是 [3,1,0,2]
理解题意
通过题意,我们可以将信息整理如下:
- 题目给出两个数,第一个代表返回的数组的长度要满足 2^n-1 个数,第二个代表返回数组第一个元素值
- 要求我们返回的结果必须满足给定的规则
做题思路
看生成规则,相邻每一个数的二进制表示都只有一位不同,并且 p[0] 位置左右两边也是只相差一个位。看这描述很容易就可以想到格雷码。格雷码就是相邻两个数之间只相差一个位。
格雷码的生成规则也很简单。从0开始,翻转一次,翻转后的数的最高位变为1,这是一位格雷码。如下:
0
1
二位格雷码则是在一位格雷码上应用上面的规则,同样是翻转,翻转后的数的最高位变为1,就成了2位格雷码。如下
0 00 00
1 01 01
-镜像-> -高位取1->
01 11
00 10
这样就是 0 1 3 2 四个数。那么,题目给的 n,代表就是n位格雷码,只要循环应用规则就可以了。
还有题目限制第一个数是 start,那么我们需要将生成的序列中的 start 值移动到第一个位置即可。参见题目 轮转数组
那么步骤就很简单了,如下:
- 生成对应的格雷码
- 找到第一个位置的数,将数组内容进行轮转
代码实现
代码实现如下: