algorithm - 在 O(n) 中对两个数组进行排序(时间和空间)
问题描述
给定两个(可能未排序的)数组,
A
以及交换元素B
的操作and ,您需要返回最小的交换次数,以便两个数组严格增加(或者如果不可能)swap(A, B, i)
A[i]
B[i]
-1
我很快就想出了一个贪婪的解决方案(如果你愿意,我可以附上代码)但显然在某些情况下它不会产生正确的答案(我不知道)。
为什么贪婪的方法不够好?达到最少掉期数量的替代方法是什么?
编辑:
这是我的代码
def solution(A, B):
n = len(A)
swaps = 0
for i in range(1, n):
if A[i] > A[i - 1] and B[i] > B[i - 1]:
continue
if A[i] < A[i - 1] and B[i] < B[i - 1]:
return -1
elif A[i] < A[i - 1]:
if B[i - 1] < A[i]:
A[i], B[i] = B[i], A[i]
swaps += 1
else:
return -1
else:
# B[i] < B[i - 1]
if A[i - 1] < B[i]:
A[i], B[i] = B[i], A[i]
swaps += 1
else:
return -1
return swaps
# test
assert(solution([5, 3, 7, 7, 10], [1, 6, 6, 9, 9]))
解决方案
您可以使用 DP 来实现:
一种方法可以是:对于每一对 A[i] 和 B[i],我们可以选择交换或不交换。所以我们定义了两个 dp 数组,keep[i] 表示如果我们不交换 A[i] 和 B[i],交换的最小次数是多少。swap[i] 是交换 A[i] 和 B[i] 的最小交换次数。
A[i] > A[i -1] && B[i] > B[i - 1],如果我们选择保留,我们应该保留之前的i-1个元素。所以keep[i] = keep[i - 1] 如果我们选择交换,为了保持排序顺序,我们必须交换前面的第i-1个元素。所以交换[i] = 交换[i - 1] + 1;
A[i] > B[i - 1] && B[i] > A[i - 1] 如果我们选择保持,keep[i] = Math.min(keep[i], swap[i - 1])如果我们选择交换,swap[i] = Math.min(swap[i], keep[i - 1] + 1)
对于 A[i] < B[i - 1] 等情况,返回 -1
时间复杂度:O(n)
推荐阅读
- python-3.x - 从请求的数据流 django 读取后,您无法访问正文
- excel - 考虑到“13:12:00”作为日期,我如何解决 Excel?
- node.js - 更新 Jest 测试库后出现意外的令牌 (SyntaxError)
- ruby - 为什么 ruby-filemagic-0.7.2 完成安装后会抛出此消息
- algorithm - 对 FIFO 页面替换算法的实际示例感到困惑?
- elasticsearch - 嵌套聚合返回计数值桶的弹性搜索查询是什么?
- javascript - 掷骰子 - Javascript 无法正常工作且图像无法上传
- php - 如何在代码 PHP 中获取文件 url 和文件路径
- python - 如何通过 Python 代码模拟导出 CSV 功能(其中
- r - 用于回归的 for 循环中的 try-catch