📅  最后修改于: 2023-12-03 15:26:47.535000             🧑  作者: Mango
在排序算法中,交换对是指数组中的两个元素(位置不一定相邻),如果交换这两个元素会使数组变得有序,那么这两个元素就是交换对。给定一个整数数组nums和一个整数k,如果只能交换一对指针i和j(i < j)满足i <= k <= j,以使得 nums是一个有序数组,则返回 true;否则,返回 false。
暴力枚举的思路是枚举每一个符合要求的交换对,看看是否能使数组有序。具体实现步骤如下:
时间复杂度:O(n^2)
贪心的思路是尽量将较小数移动到左边,较大数移动到右边。具体实现步骤如下:
时间复杂度:O(n),比暴力枚举的时间复杂度更优。
def canSort(nums: List[int], k: int) -> bool:
# 暴力枚举
for i in range(k+1, len(nums)):
for j in range(i+1, len(nums)):
if nums[i] < nums[k] and nums[j] < nums[k] and nums[i] > nums[j]:
# 交换nums[i]和nums[j]
nums[i], nums[j] = nums[j], nums[i]
# 判断是否有序
for m in range(1, len(nums)):
if nums[m] < nums[m-1]:
# 还原数组
nums[i], nums[j] = nums[j], nums[i]
break
else:
return True
else:
return False
def canSort2(nums: List[int], k: int) -> bool:
# 贪心
i, j = k+1, k+1
while j < len(nums):
if nums[j] < nums[k]:
# 记录最后一个符合要求的交换对
i = j
j += 1
# 找到第一个比nums[k]小的数
for m in range(k, -1, -1):
if nums[m] > nums[i]:
# 记录第一个符合要求的交换对
j = m
break
else:
return False
# 交换nums[i]和nums[j]
nums[i], nums[j] = nums[j], nums[i]
# 判断是否有序
for m in range(1, len(nums)):
if nums[m] < nums[m-1]:
# 还原数组
nums[i], nums[j] = nums[j], nums[i]
break
else:
return True
return False
以上是两种常见的实现方法,其中贪心算法的时间复杂度更优,推荐使用。