📅  最后修改于: 2023-12-03 14:55:20.559000             🧑  作者: Mango
有一个长度为 $n$ 的整数数组 $arr$,你需要重新排列数组,使得对于任意的 $i$,都满足 $\exists j$,满足 $0\leq j<i~~&&~~arr[j]=arr[i]$,并且 $j+i$ 是 3 的倍数。其中 $&&$ 表示逻辑与运算。
请你返回重新排列后的数组。
如果有多种不同的答案,需要返回其中任意一种。
如果无法满足上述条件,请返回一个空数组。
输入:
arr = [1, 3, 2, 3, 1]
输出:
[1, 3, 2, 1, 3]
根据题意,对于任意的 $i$,都要满足 $\exists j$,使得 $j+i$ 是 3 的倍数,也就是说,$j$ 和 $i$ 同余,即 $j\equiv -i\bmod 3$。
因此,我们可以使用桶排序的思想,将数组中每个元素对 3 取余之后,将余数相同的元素放在同一个桶中。
接下来,我们从小到大依次遍历每个桶,并将桶内的元素插入到数组 $res$ 中,插入时,我们需要选择一个满足条件的位置插入,也就是找到一个位置 $i$,满足 $j<i$ 且 $j\equiv -i\bmod 3$。
如果遍历完所有的桶之后,仍有元素没被插入,说明无法满足上述条件,此时直接返回空数组。
class Solution:
def rearrangeArray(self, nums: List[int]) -> List[int]:
count = [0] * 3
for num in nums:
count[num % 3] += 1
res = [0] * len(nums)
pos = [0, count[0], count[0] + count[1], len(nums)]
index = [0, 1, 2] * ((len(nums) + 2) // 3)
for i in range(4):
start, end = pos[index[i]], pos[index[i+1]]
for j in range(start, end):
k = j - start if i < 3 else 2 * (j - start)
res[3*k + i%3] = nums[j]
for i in range(1, len(nums)):
if (res[i-1]+i) % 3 == 0:
res[i-1], res[i] = res[i], res[i-1]
for i in range(len(nums)):
if i > 0 and (res[i]+res[i-1]) % 3 == 0:
return []
return res