作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/minimum-swaps-to-make-sequences-increasing/description/

题目描述

We have two integer sequences A and B of the same non-zero length.

We are allowed to swap elements A[i] and B[i]. Note that both elements are in the same index position in their respective sequences.

At the end of some number of swaps, A and B are both strictly increasing. (A sequence is strictly increasing if and only if A[0] < A[1] < A[2] < ... < A[A.length - 1].)

Given A and B, return the minimum number of swaps to make both sequences strictly increasing. It is guaranteed that the given input always makes it possible.

Example:

Input: A = [1,3,5,4], B = [1,2,3,7]
Output: 1
Explanation:
Swap A[3] and B[3]. Then the sequences are:
A = [1, 3, 5, 7] and B = [1, 2, 3, 4]
which are both strictly increasing.

Note:

  • A, B are arrays with the same length, and that length will be in the range [1, 1000].
  • A[i], B[i] are integer values in the range [0, 2000].

题目大意

一个字符串中有0有1,问最少翻转多少个字符能够使得这个字符串编程一个单调递增的字符串。

解题方法

动态规划

这个题和周赛926. Flip String to Monotone Increasing基本一模一样,如果我早点把这个题搞明白的话,周赛的926应该也能做出来了。926题我写的非常的详细,是我写的最认真的一次,强烈建议看下926题的动态规划部分。

我是看了画画酱的讲义的,如下图。这个题也是需要做交换,可以定义两个数组keep和swap,这两个数组的含义是我们交换或者不交换第i个位置使得两个数组都保持严格的单调递增需要进行的交换数量。

那么,当A[i] > A[i - 1] and B[i] > B[i - 1]时,我们可以不交换当前的数字,这个时候前面的数字也不能交换;也可以交换当前的数字,同时需要把前面的数字也进行交换。即,这种情况下,前面的位置和现在的位置做的是同样的交换。

在做了上面的操作之后,我们得到的仍然是有序的部分,但是没有结束,因为我们可能还会出现A[i] > B[i - 1] and B[i] > A[i - 1]这种交叉的情况。这个时候考虑前面的位置和现在的位置做相反的交换。

当A[i] > B[i - 1] and B[i] > A[i - 1]时,我们如果不交换当前的数字,同时对前面的位置强制交换,判断交换后的次数是不是比当前的交换次数少;如果我们交换这个位置,同时强制前面的数字不交换,那么当前的交换次数应该是前面不交换的次数+1和当前交换次数的最小值。

上面两种判断并不是if-else的关系,因为,这两种情况同时存在。我们通过这两种情况,考虑了4种情况:当前位置换、不换与前面的位置换、不换的组合。注意第二个判断里面求最小值是相对于自身做比较的,因为我们不一定需要对前面的位置进行操作。

另外,需要注意的是,一般情况的dp初始化都是0或者1,但是这个题需要求最小值,其实已经提醒我们不是0或者1.实际上,需要使用无穷大表示初始情况下,还没有做翻转操作时交换次数应该是无穷多。而不是0表示初始情况下不用交换就能到达有序。

时间复杂度是O(N),空间复杂度是O(N).

class Solution(object):
def minSwap(self, A, B):
"""
:type A: List[int]
:type B: List[int]
:rtype: int
"""
N = len(A)
keep = [float('inf')] * N
swap = [float('inf')] * N
keep[0] = 0
swap[0] = 1
for i in range(1, N):
if A[i] > A[i - 1] and B[i] > B[i - 1]:
keep[i] = keep[i - 1]
swap[i] = swap[i - 1] + 1
if A[i] > B[i - 1] and B[i] > A[i - 1]:
keep[i] = min(keep[i], swap[i - 1])
swap[i] = min(swap[i], keep[i - 1] + 1)
return min(keep[N - 1], swap[N - 1])

这个题如果改成和926题一样的二维数组的dp的话,应该这么写,其实和上面的做法没有任何区别。

class Solution(object):
def minSwap(self, A, B):
"""
:type A: List[int]
:type B: List[int]
:rtype: int
"""
N = len(A)
dp = [[float('inf'), float('inf')] for _ in range(N)]
dp[0][0] = 0
dp[0][1] = 1
for i in range(1, N):
if A[i] > A[i - 1] and B[i] > B[i - 1]:
dp[i][0] = dp[i - 1][0]
dp[i][1] = dp[i - 1][1] + 1
if A[i] > B[i - 1] and B[i] > A[i - 1]:
dp[i][0] = min(dp[i][0], dp[i - 1][1])
dp[i][1] = min(dp[i][1], dp[i - 1][0] + 1)
return min(dp[N - 1][0], dp[N - 1][1])

显然,上面的做法中,每次dp转移操作只和前面的一个状态有关,所以,可以优化空间复杂度到O(1)。对于每次

代码如下:

class Solution(object):
def minSwap(self, A, B):
"""
:type A: List[int]
:type B: List[int]
:rtype: int
"""
N = len(A)
keep, swap = 0, 1
for i in range(1, N):
curswap, curkeep = float('inf'), float('inf')
if A[i] > A[i - 1] and B[i] > B[i - 1]:
curkeep, curswap = keep, swap + 1
if A[i] > B[i - 1] and B[i] > A[i - 1]:
curkeep, curswap = min(curkeep, swap), min(curswap, keep + 1)
keep, swap = curkeep, curswap
return min(keep, swap)

参考资料

https://leetcode.com/problems/flip-string-to-monotone-increasing/discuss/183859/Java-DP-using-O(N)-time-and-O(1)-space

日期

2018 年 10 月 21 日 —— 新的一周又开始了

【LeetCode】801. Minimum Swaps To Make Sequences Increasing 解题报告(Python)的更多相关文章

  1. LeetCode 801. Minimum Swaps To Make Sequences Increasing

    原题链接在这里:https://leetcode.com/problems/minimum-swaps-to-make-sequences-increasing/ 题目: We have two in ...

  2. [LeetCode] 801. Minimum Swaps To Make Sequences Increasing 最少交换使得序列递增

    We have two integer sequences A and B of the same non-zero length. We are allowed to swap elements A ...

  3. 801. Minimum Swaps To Make Sequences Increasing

    We have two integer sequences A and B of the same non-zero length. We are allowed to swap elements A ...

  4. 【leetcode】801. Minimum Swaps To Make Sequences Increasing

    题目如下: We have two integer sequences A and B of the same non-zero length. We are allowed to swap elem ...

  5. 801. Minimum Swaps To Make Sequences Increasing 为使两个数组严格递增,所需要的最小交换次数

    [抄题]: We have two integer sequences A and B of the same non-zero length. We are allowed to swap elem ...

  6. [LeetCode] Minimum Swaps To Make Sequences Increasing 使得序列递增的最小交换

    We have two integer sequences A and B of the same non-zero length. We are allowed to swap elements A ...

  7. [Swift]LeetCode801. 使序列递增的最小交换次数 | Minimum Swaps To Make Sequences Increasing

    We have two integer sequences A and B of the same non-zero length. We are allowed to swap elements A ...

  8. 【LeetCode】926. Flip String to Monotone Increasing 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 Prefix计算 动态规划 参考资料 日期 题目地址 ...

  9. 【LeetCode】26. Remove Duplicates from Sorted Array 解题报告(Python&C++&Java)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 双指针 日期 [LeetCode] https:// ...

随机推荐

  1. CentOS6.9 内核升级详解

    内核进行的是应用软件和计算机硬件的交互工作在计算机科学中,内核(英语:kernel)又称核心,是一个计算机程序,用来管理软件发出的数据I/O(输入与输出)要求,将这些要求转译为数据处理的指令,交由中央 ...

  2. Notepad++—英文版卡框架翻译

    用到了,就积累到这里,不急一时,慢慢沉淀. 一.File 二.Edit 三.Search 四.View视图 Always on top  #总在最前 Toggle full screen mode  ...

  3. Office2020-2021 离线安装教程

    首先:先安装两个 net .再安装 office 如下: DownFile:https://pan.baidu.com/s/19iykxwofXK36wWY5w4GVFg  codenum:6666

  4. 总结HashSet以及分析部分底层源码

    总结HashSet以及分析部分底层源码 1. HashSet继承的抽象类和实现的接口 继承的抽象类:AbstractSet 实现了Set接口 实现了Cloneable接口 实现了Serializabl ...

  5. day08 索引的创建与慢查询优化

    day08 索引的创建与慢查询优化 昨日内容回顾 视图 视图:将SQL语句查询结果实体化保存起来,方便下次查询使用. 视图里面的数据来源于原表,视图只有表结构 # 创建视图 create view 视 ...

  6. day11 系统安全

    day11 系统安全 复习总结 文件 1.创建 格式:touch [路径] [root@localhost ~]# touch 1.txt # 当前路径创建 [root@localhost ~]# t ...

  7. Spark基础:(七)Spark Streaming入门

    介绍 1.是spark core的扩展,针对实时数据流处理,具有可扩展.高吞吐量.容错. 数据可以是来自于kafka,flume,tcpsocket,使用高级函数(map reduce filter ...

  8. 容器之分类与各种测试(三)——list部分用法

    list是一个双向链表 例程 #include<stdexcept> #include<memory.h> #include<string> #include< ...

  9. Java面试基础--(出现次数最多的字符串)

    题目:给定字符串,求出现次数最多的那个字母及次数,如有多个 重复则都输出. eg,String data ="aaavzadfsdfsdhshdWashfasdf": 思路: 1. ...

  10. Java易错小结

    String 相关运算 String使用是注意是否初始化,未初始化的全部为null.不要轻易使用 string.isEmpty()等,首先确保string非空. 推荐使用StringUtils.isN ...