n位格雷码生成问题求助:HackerRank测试用例未通过
解决格雷码序列输出的末尾测试用例问题
首先咱们先把题目要求的输出规则理清楚,从你给的示例里能提炼出明确规律:
对于n位格雷码序列(总长度为2^n),需要输出从索引2^n - n开始到序列末尾的所有元素,每个元素以n位二进制字符串形式呈现。
咱们验证下这个规律:
- n=1:
2^1 -1 =1,从索引1到末尾(仅元素"1"),和示例输出一致; - n=2:
2^2 -2=2,从索引2到3(元素"11"、"10"),完全匹配示例; - n=3:
2^3 -3=5,从索引5到7(元素"111"、"101"、"100"),和示例输出吻合; - n=4:
2^4 -4=12,从索引12到15(元素"1010"、"1011"、"1001"、"1000"),和你给出的示例片段完全对应。
导致末尾测试用例失败的常见原因
如果你的代码在n较小时能通过,但遇到n=65这类大数值就报错,大概率是这两个问题:
1. 整数溢出问题
当n=65时,2^65是一个远超64位整数范围的数值(2^64已经是18446744073709551616,2^65是它的两倍)。如果用普通的64位整数类型存储,直接就会溢出,导致索引计算完全错误。
- 解决办法:用支持任意精度大整数的类型,比如Python的
int(天生支持超大整数)、Java的BigInteger、C#的BigInteger等。
2. 生成整个序列导致内存爆炸
直接生成2^65长度的格雷码序列根本不可能——这个数值大到内存根本装不下。其实完全不需要生成整个序列,我们可以直接计算目标范围内每个索引对应的格雷码。
格雷码的核心公式是:gray_code = index ^ (index >> 1)。我们只需要遍历从start_index = 2^n -n到end_index = 2^n -1的每个索引,计算对应的格雷码,再格式化为n位二进制字符串(前面补零)就行。
示例Python代码
def generate_target_gray_codes(n): if n == 0: return [] # 计算起始和结束索引,Python的int无溢出问题 start = (1 << n) - n end = (1 << n) - 1 result = [] for idx in range(start, end + 1): gray = idx ^ (idx >> 1) # 格式化为n位二进制,前面补零 gray_str = bin(gray)[2:].zfill(n) result.append(gray_str) return result # 测试示例 print(' '.join(generate_target_gray_codes(1))) # 输出: 1 print(' '.join(generate_target_gray_codes(2))) # 输出: 11 10 print(' '.join(generate_target_gray_codes(3))) # 输出: 111 101 100 print(' '.join(generate_target_gray_codes(4))) # 输出: 1010 1011 1001 1000
为什么这个代码能过大n测试?
- 不需要生成整个格雷码序列,只遍历n个元素(
end - start +1 =n),时间复杂度是O(n),内存占用也是O(n),完全能处理n=65的情况; - Python的整数没有溢出限制,计算
2^65毫无压力。
如果你用其他语言开发,比如Java,记得用BigInteger来计算2^n和索引,再逐个计算格雷码并格式化即可。
内容的提问来源于stack exchange,提问作者Jees K Denny
相关产品推荐
相关产品推荐

