2026-04-20: 二进制反射排序。用go语言, 把数组里每个数先转成二

完美体育在线直播
你的位置:完美体育在线直播 > 新闻动态 > 2026-04-20: 二进制反射排序。用go语言, 把数组里每个数先转成二
2026-04-20: 二进制反射排序。用go语言, 把数组里每个数先转成二
发布日期:2026-04-30 18:04    点击次数:183

2026-04-20:二进制反射排序。用go语言,把数组里每个数先转成二进制;对它的二进制表示做“二进制反射”(把二进制位从左到右反过来,前导零不计入);再把反射后的二进制串转回十进制,这个结果就是该元素的“反射值”。

然后按所有元素的反射值从小到大排序;若两个数的反射值相同,则比较它们原始的数值大小,原数更小的排在前面。

最后返回排序后的数组。

1

1

输入: nums = [3,6,5,8]。

输出: [8,3,6,5]。

解释:

二进制反射值为:

3 -> (二进制) 11 -> (反转) 11 -> 3

6 -> (二进制) 110 -> (反转) 011 -> 3

5 -> (二进制) 101 -> (反转) 101 -> 5

8 -> (二进制) 1000 -> (反转) 0001 -> 1

根据反射值排序为 [8, 3, 6, 5]。

注意,3 和 6 的反射值相同,因此需要按原始值的升序排列。

题目来自力扣3769。

二进制反射排序完整过程详解

第一步:明确核心定义

1. 二进制转换:把每个十进制数字转为无前导零的二进制字符串

2. 二进制反射:将二进制字符串整体反转,忽略反转后产生的前导零,再转回十进制,得到反射值

3. 排序规则:

• 优先按反射值从小到大排序

• 反射值相同时,按原始数值从小到大排序

第二步:逐个计算每个数字的反射值

我们对数组 [3, 6, 5, 8] 中的每个元素,依次计算反射值:

1. 数字 3

• 十进制 → 二进制(无前导零):11

• 二进制反射(反转):11

• 反转后转回十进制:3

• 反射值 = 3,原始值 = 3

2. 数字 6

• 十进制 → 二进制(无前导零):110

• 二进制反射(反转):011(忽略前导零 → 11)

• 反转后转回十进制:3

• 反射值 = 3,原始值 = 6

3. 数字 5

• 十进制 → 二进制(无前导零):101

• 二进制反射(反转):101

• 反转后转回十进制:5

• 反射值 = 5,原始值 = 5

4. 数字 8

• 十进制 → 二进制(无前导零):1000

• 二进制反射(反转):0001(忽略前导零 → 1)

• 反转后转回十进制:1

• 反射值 = 1,原始值 = 8

第三步:整理所有元素的「反射值+原始值」

整理后结果:

• 8:反射值 1,原始值 8

• 3:反射值 3,原始值 3

• 6:反射值 3,原始值 6

• 5:反射值 5,原始值 5

第四步:按照排序规则排序

1. 第一优先级:反射值升序

反射值大小:1

所以 8(1)排第一,5(5)排最后;3 和 6 反射值都是 3,并列中间。

2. 第二优先级:反射值相同时,原始值升序

第五步:得到最终结果

排序后数组:[8, 3, 6, 5]

时间复杂度 & 额外空间复杂度分析

1. 时间复杂度

• 核心操作是自定义排序,Go 语言 slices.SortFunc 底层使用快速排序/优化排序,时间复杂度为 O(n log n)(n 是数组长度)。

• 排序过程中,每个元素会计算一次反射值,计算反射值是固定位数的二进制操作(常数时间 O(1))。

• 总时间复杂度:O(n log n)。

2. 额外空间复杂度

• 代码直接在原数组上进行排序,没有创建新的数组存储数据。

• 排序和计算反射值仅使用了常数个临时变量。

• 总额外空间复杂度:O(1)(原地操作,常数空间)。

总结

1. 完整执行流程:计算每个数的二进制→二进制反转→计算反射值→按反射值排序→反射值相同按原数排序→输出结果

2. 时间复杂度:O(n log n)

3. 额外空间复杂度:O(1)(原地排序,无额外数组开销)

Go完整代码如下:

package main

import (

"cmp"

"fmt"

"math/bits"

"slices"

)

func sortByReflection(nums []int) []int {

slices.SortFunc(nums, func(a, b int)int {

revA := int(bits.Reverse(uint(a)) >> bits.LeadingZeros(uint(a)))

revB := int(bits.Reverse(uint(b)) >> bits.LeadingZeros(uint(b)))

return cmp.Or(revA-revB, a-b)

})

return nums

}

func main {

nums := []int{3, 6, 5, 8}

result := sortByReflection(nums)

fmt.Println(result)

}

Python完整代码如下:

# -*-coding:utf-8-*-

def sort_by_reflection(nums):

def reverse_bits(n):

# 将整数转换为二进制字符串,反转并去掉末尾的0

if n == 0:

return0

# 获取二进制表示(去掉'0b'前缀)

binary = bin(n)[2:]

# 反转字符串

reversed_binary = binary[::-1]

# 转换为整数

returnint(reversed_binary, 2)

def sort_key(num):

rev = reverse_bits(num)

# Python的排序是稳定的,我们通过返回元组来实现多级排序

return (rev, num)

# 使用sort方法进行原地排序

nums.sort(key=sort_key)

return nums

def main:

nums = [3, 6, 5, 8]

result = sort_by_reflection(nums)

print(result)

if __name__ == "__main__":

main

C++完整代码如下:

#include

#include

#include

#include

#include

int reverseBits(int n) {

if (n == 0) return0;

unsigned int u = static_cast(n);

// C++23 提供 std::bit_reverse

// 如果编译器支持,可以使用:#if __cpp_lib_bit_reverse

// 否则使用手动实现

// 手动实现32位反转

u = ((u & 0x55555555) > 1);

u = ((u & 0x33333333) > 2);

u = ((u & 0x0F0F0F0F) > 4);

u = ((u & 0x00FF00FF) > 8);

u = (u > 16);

return static_cast(u);

}

int leadingZeros(int n) {

if (n == 0) return32;

return std::countl_zero(static_cast(n));

}

std::vector sortByReflection(std::vector& nums) {

std::ranges::sort(nums, [](int a, int b) {

int revA = reverseBits(a) >> leadingZeros(a);

int revB = reverseBits(b) >> leadingZeros(b);

if (revA != revB) {

return revA

}

return a

});

return nums;

}

int main {

std::vector nums = {3, 6, 5, 8};

std::vector result = sortByReflection(nums);

for (size_t i = 0; i

std::cout

}

std::cout

return0;

}

我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。

欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。



Powered by 完美体育在线直播 @2013-2022 RSS地图 HTML地图

Copyright Powered by365站群 © 2013-2024