
题目描述
给你一个整数数组 nums。
二进制反射 是对一个 正整数 的二进制表示按顺序反转(忽略前导零)后,将反转得到的二进制数转为十进制的结果。
请按每个元素的二进制反射值的 升序 对数组进行排序。如果两个不同的数字具有相同的二进制反射值,则 较小 的原始数字应排在前面。
返回排序后的数组。
示例 1:
输入: nums = [4,5,4]
输出: [4,4,5]
解释:
二进制反射值为:
- 4 -> (二进制)
100 -> (反转) 001 -> 1 - 5 -> (二进制)
101 -> (反转) 101 -> 5 - 4 -> (二进制)
100 -> (反转) 001 -> 1
根据反射值排序为
[4, 4, 5]。
示例 2:
输入: 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 的反射值相同,因此需要按原始值的升序排列。
提示:
1 <= nums.length <= 100 1 <= nums[i] <= 109
解法
方法一:自定义排序
我们定义一个函数 \(f(x)\) 来计算整数 \(x\) 的二进制反射值。具体地,我们不断取出 \(x\) 的最低位,并将其添加到结果 \(y\) 的末尾,直到 \(x\) 变为 \(0\)。
然后,我们对数组 \(\textit{nums}\) 进行排序,排序的关键字为每个元素的二进制反射值和原始值的元组 \((f(x), x)\)。这样可以确保当两个元素的二进制反射值相同时,较小的原始值会排在前面。
最后,我们返回排序后的数组。
时间复杂度 \(O(n \times \log n)\),空间复杂度 \(O(\log n)\)。其中 \(n\) 是数组 \(\textit{nums}\) 的长度。
| class Solution:
def sortByReflection(self, nums: List[int]) -> List[int]:
def f(x: int) -> int:
y = 0
while x:
y = y << 1 | (x & 1)
x >>= 1
return y
nums.sort(key=lambda x: (f(x), x))
return nums
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 | class Solution {
public int[] sortByReflection(int[] nums) {
int n = nums.length;
Integer[] a = new Integer[n];
Arrays.setAll(a, i -> nums[i]);
Arrays.sort(a, (u, v) -> {
int fu = f(u);
int fv = f(v);
if (fu != fv) {
return Integer.compare(fu, fv);
}
return Integer.compare(u, v);
});
for (int i = 0; i < n; i++) nums[i] = a[i];
return nums;
}
private int f(int x) {
int y = 0;
while (x != 0) {
y = (y << 1) | (x & 1);
x >>= 1;
}
return y;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | class Solution {
public:
vector<int> sortByReflection(vector<int>& nums) {
auto f = [](int x) {
int y = 0;
while (x) {
y = (y << 1) | (x & 1);
x >>= 1;
}
return y;
};
sort(nums.begin(), nums.end(), [&](int a, int b) {
int fa = f(a);
int fb = f(b);
if (fa != fb) {
return fa < fb;
}
return a < b;
});
return nums;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | func sortByReflection(nums []int) []int {
f := func(x int) int {
y := 0
for x != 0 {
y = (y << 1) | (x & 1)
x >>= 1
}
return y
}
sort.Slice(nums, func(i, j int) bool {
fi := f(nums[i])
fj := f(nums[j])
if fi != fj {
return fi < fj
}
return nums[i] < nums[j]
})
return nums
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | function sortByReflection(nums: number[]): number[] {
const f = (x: number): number => {
let y = 0;
for (; x; x >>= 1) {
y = (y << 1) | (x & 1);
}
return y;
};
nums.sort((a, b) => {
const fa = f(a);
const fb = f(b);
if (fa !== fb) {
return fa - fb;
}
return a - b;
});
return nums;
}
|