📅  最后修改于: 2023-12-03 15:26:26.685000             🧑  作者: Mango
给定一个包含 $n$ 个整数的数组 $nums$,你可以交换其中的任意两个元素,最终使得数组中第一个元素为数组中的最小值,最后一个元素为数组中的最大值。
请你返回最少需要交换的次数,使得上述条件成立。
我们需要做的是将第一个元素移动到它正确的位置,同时将最后一个元素移动到它正确的位置。那么我们可以分别计算出要将第一个元素移动到的位置 $i$,以及要将最后一个元素移动到的位置 $j$,然后将它们交换位置即可。
具体而言,我们考虑第一个元素。由于第一个元素需要是整个序列的最小值,因此我们可以遍历整个数组,找到最小值所在的位置 $i$,然后将其与第一个位置交换即可。对于最后一个位置同理,找到最大值所在的位置 $j$,然后与最后一个位置交换即可。
但是,这种简单的思路并不能完全解决问题。假设最小元素和最大元素都位于数组的中间位置,那么我们只能通过多次交换才能将它们移动到正确的位置上。
因此,我们需要进行一些优化。具体而言,我们可以考虑从两端同时查找,如果遇到最小元素或最大元素就停止查找,然后交换。
具体代码如下:
class Solution:
def minMoves(self, nums: List[int]) -> int:
n = len(nums)
left, right = 0, n - 1
min_val, max_val = min(nums), max(nums)
while left < right:
if nums[left] == min_val:
nums[left], nums[right] = nums[right], nums[left]
right -= 1
elif nums[right] == max_val:
nums[left], nums[right] = nums[right], nums[left]
left += 1
else:
left += 1
right -= 1
return n - (right - left + 1)
以上算法的时间复杂度为 $O(n)$,其中 $n$ 为数组的长度。我们只需要遍历数组两遍,即可找到最小元素和最大元素所在的位置。因此,算法的时间复杂度主要由数组的遍历部分决定。
以上算法的空间复杂度为 $O(1)$。我们只需要记录最小元素和最大元素的值即可,不需要额外的空间。因此,算法的空间复杂度为常数级别。
本文介绍了如何通过最小化使第一个和最后一个元素分别成为数组中最大和最小元素所需的交换来解决问题。具体而言,我们可以从两端同时查找,如果遇到最小元素或最大元素就停止查找,然后交换。
以上算法的时间复杂度为 $O(n)$,空间复杂度为 $O(1)$。