给你一个数组nums
,数组中有2n
个元素,按 [x1,x2,...,xn,y1,y2,...,yn]
的格式排列。
请你将数组按[x1,y1,x2,y2,...,xn,yn]
格式重新排列,返回重排后的数组。
示例:
输入:
nums = [2,5,1,3,4,7]
,n = 3
输出:[2,3,5,4,1,7]
解释:由于x1 = 2, x2 = 5, x3 = 1, y1 = 3, y2 = 4, y3 = 7
,所以答案为[2,3,5,4,1,7]
来源:LeetCode 第1470题
解法:位运算
时间复杂度:O(n)
空间复杂度:O(1)
思路:
因为题目限制了每一个元素 nums[i]
最大只有可能是 1000,这就意味着每一个元素只占据了 10 个 bit
(2^10 - 1 = 1023 > 1000)
。
而一个 int
有 32 个bit
,所以我们还可以使用剩下的 22 个 bit
做存储。实际上,每个int
,我们再借 10 个bit
用就好了。
因此,在下面的代码中,每一个 nums[i]
的最低的十个bit
(0 - 9 位),我们用来存储原来 nums[i]
的数字;再往前的十个 bit
(10 - 19 位),我们用来存储重新排列后正确的数字是什么。
在循环中,我们每次首先计算 nums[i] 对应的重新排列后的索引j
,之后,取nums[i]
的低 10 位(nums[i] & 1023
),即 nums[i]
的原始信息,把他放到 nums[j]
的高十位上。
最后,每个元素都取高 10 位的信息(num >> 10
),即是答案。
代码:
def shuffle(self, nums: List[int], n: int) -> List[int]:
for i in range(2 * n):
j = 2 * i if i < n else 2 * (i - n) + 1
nums[j] |= (nums[i] & 1023) << 10
return [num >> 10 for num in nums]