1. 解题思路
这一题是Leetcode周赛481的第三题,是一道hard难度的题目。
这一题的话,不难证明,如果可以存在 n n n个元素可以交换满足均不对应forbidden的元素,那么其所需的交换次数最少为 ⌈ n 2 ⌉ \lceil\frac{n}{2}\rceil ⌈2n⌉。
剩下的,我们就是看一下哪些情况下无法完成交换,其实这就两种情况:
- forbidden当中某一个元素数目过多,以至于原始数组中无法找到足够的其他元素填充到对应的位置当中;
- 原始数组中某一个元素数目过多,以至于forbidden数组当中至少会有一个forbid的位置会被放入对应的元素。
因此,我们只需要排除一下以上两种情况,然后找出所有需要交换的元素的个数,然后计算一下 ⌈ n 2 ⌉ \lceil\frac{n}{2}\rceil ⌈2n⌉即可。
需要注意的是,一般情况下需要交换的元素个数就是原始数组与forbidden数组一致的元素个数,但是如果其中有一个单一元素占比过高以至于其他需要的元素不够用于交换时,我们需要额外补充一些原本不需要进行交换的元素来与之进行交换。
2. 代码实现
给出python代码实现如下:
class Solution:
def minSwaps(self, nums: List[int], forbidden: List[int]) -> int:
swap = []
for num, fbd in zip(nums, forbidden):
if num == fbd:
swap.append(num)
if len(swap) == 0:
return 0
cnt = Counter(swap)
tot1, tot2 = Counter(nums), Counter(forbidden)
for key, val in cnt.items():
if val > len(nums) - tot1[key]:
return -1
elif tot1[key] > len(nums) - tot2[key]:
return -1
need_swap = max(len(swap), max(cnt.values()) * 2)
return (need_swap+1) // 2
提交代码评测得到:耗时139ms,占用内存47.36MB。
898

被折叠的 条评论
为什么被折叠?



