Java C++算法题解leetcode801使序列递增的最小交换次数

 更新时间:2022年10月10日 17:13:03   作者:AnjaVon  
这篇文章主要为大家介绍了Java C++题解leetcode801使序列递增的最小交换次数示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

题目要求

思路:状态机DP

实现一:状态机

Java

class Solution {
    public int minSwap(int[] nums1, int[] nums2) {
        int n = nums1.length;
        int[][] f = new int[n][2];
        for (int i = 1; i < n; i++)
            f[i][0] = f[i][1] = n + 10; // 初始化
        f[0][1] = 1;
        for (int i = 1; i < n; i++) {
            if (nums1[i - 1] < nums1[i] && nums2[i - 1] < nums2[i]) {
                f[i][0] = f[i - 1][0];
                f[i][1] = f[i - 1][1] + 1;
            }
            if (nums2[i - 1] < nums1[i] && nums1[i - 1] < nums2[i]) {
                f[i][0] = Math.min(f[i][0], f[i - 1][1]);
                f[i][1] = Math.min(f[i][1], f[i - 1][0] + 1); 
            }
        }
        return Math.min(f[n - 1][0], f[n - 1][1]);
    }
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

C++

class Solution {
public:
    int minSwap(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size();
        int f[n][2];
        for (int i = 1; i < n; i++)
            f[i][0] = f[i][1] = n + 10; // 初始化
        f[0][0] = 0;
        f[0][1] = 1;
        for (int i = 1; i < n; i++) {
            if (nums1[i - 1] < nums1[i] && nums2[i - 1] < nums2[i]) {
                f[i][0] = f[i - 1][0];
                f[i][1] = f[i - 1][1] + 1;
            }
            if (nums2[i - 1] < nums1[i] && nums1[i - 1] < nums2[i]) {
                f[i][0] = min(f[i][0], f[i - 1][1]);
                f[i][1] = min(f[i][1], f[i - 1][0] + 1); 
            }
        }
        return min(f[n - 1][0], f[n - 1][1]);
    }
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

Rust

impl Solution {
    pub fn min_swap(nums1: Vec<i32>, nums2: Vec<i32>) -> i32 {
        let n = nums1.len();
        let mut f = vec![vec![n + 10; 2 as usize]; n as usize];
        f[0][0] = 0;
        f[0][1] = 1;
        for i in 1..n {
            if (nums1[i - 1] < nums1[i] && nums2[i - 1] < nums2[i]) {
                f[i][0] = f[i - 1][0];
                f[i][1] = f[i - 1][1] + 1;
            }
            if (nums2[i - 1] < nums1[i] && nums1[i - 1] < nums2[i]) {
                f[i][0] = f[i][0].min(f[i - 1][1]);
                f[i][1] = f[i][1].min(f[i - 1][0] + 1); 
            }
        }
        f[n - 1][0].min(f[n - 1][1]) as i32
    }
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

实现二:滚动数组

  • 因为状态变换仅依赖于前一项,所以可以改为使用滚动数组优化空间;
    • 也就是把dp数组从n×2改为2×2大小,idx模1交替存储。

Java

class Solution {
    public int minSwap(int[] nums1, int[] nums2) {
        int n = nums1.length;
        int[][] f = new int[2][2];
        f[0][1] = 1;
        for (int i = 1; i < n; i++) {
            int tru = n + 10, fal = n + 10; // 暂存
            int pre = (i - 1) & 1, cur = i & 1;
            if (nums1[i - 1] < nums1[i] && nums2[i - 1] < nums2[i]) {
                tru = f[pre][0];
                fal = f[pre][1] + 1;
            }
            if (nums2[i - 1] < nums1[i] && nums1[i - 1] < nums2[i]) {
                tru = Math.min(tru, f[pre][1]);
                fal = Math.min(fal, f[pre][0] + 1); 
            }
            // 更新
            f[cur][0] = tru;
            f[cur][1] = fal;
        }
        return Math.min(f[(n - 1) & 1][0], f[(n - 1) & 1][1]);
    }
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

C++

class Solution {
public:
    int minSwap(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size();
        int f[2][2];
        f[0][0] = 0;
        f[0][1] = 1;
        for (int i = 1; i < n; i++) {
            int tru = n + 10, fal = n + 10; // 暂存
            int pre = (i - 1) & 1, cur = i & 1;
            if (nums1[i - 1] < nums1[i] && nums2[i - 1] < nums2[i]) {
                tru = f[pre][0];
                fal = f[pre][1] + 1;
            }
            if (nums2[i - 1] < nums1[i] && nums1[i - 1] < nums2[i]) {
                tru = min(tru, f[pre][1]);
                fal = min(fal, f[pre][0] + 1); 
            }
            // 更新
            f[cur][0] = tru;
            f[cur][1] = fal;
        }
        return min(f[(n - 1) & 1][0], f[(n - 1) & 1][1]);
    }
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

Rust

impl Solution {
    pub fn min_swap(nums1: Vec<i32>, nums2: Vec<i32>) -> i32 {
        let n = nums1.len();
        let mut f = vec![vec![n + 10; 2 as usize]; 2 as usize];
        f[0][0] = 0;
        f[0][1] = 1;
        for i in 1..n {
            let (mut tru, mut fal) = (n + 10, n + 10);
            let (pre, cur) = ((i - 1) & 1, i & 1);
            if (nums1[i - 1] < nums1[i] && nums2[i - 1] < nums2[i]) {
                tru = f[pre][0];
                fal = f[pre][1] + 1;
            }
            if (nums2[i - 1] < nums1[i] && nums1[i - 1] < nums2[i]) {
                tru = tru.min(f[pre][1]);
                fal = fal.min(f[pre][0] + 1); 
            }
            f[cur][0] = tru;
            f[cur][1] = fal;
        }
        f[(n - 1) & 1][0].min(f[(n - 1) & 1][1]) as i32
    }
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

总结

这个不用操作原数组直接改状态的思路还有一点绕,看了好几遍题解又推了几个例子才理解过来。

以上就是Java C++题解leetcode801使序列递增的最小交换次数的详细内容,更多关于Java C++ 序列递增最小交换次数的资料请关注脚本之家其它相关文章!

相关文章

  • Python文件高级操作函数之文件信息获取与目录操作

    Python文件高级操作函数之文件信息获取与目录操作

    这篇文章主要介绍了Python文件高级操作函数之文件信息获取与目录操作,在Python中,内置了文件(File)对象。在使用文件对象时,首先需要通过内置的open()方法创建一个文件对象,然后通过该对象提供的方法进行一些基本文件操作,需要的朋友可以参考下
    2023-05-05
  • 基于log4j2.properties踩坑与填坑

    基于log4j2.properties踩坑与填坑

    这篇文章主要介绍了log4j2.properties踩坑与填坑方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • 利用Spring Data MongoDB持久化文档数据的方法教程

    利用Spring Data MongoDB持久化文档数据的方法教程

    这篇文章主要给大家介绍了关于利用Spring Data MongoDB持久化文档数据的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-08-08
  • Java数据结构之队列(动力节点Java学院整理)

    Java数据结构之队列(动力节点Java学院整理)

    队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表。 这篇文章详细给大家介绍了java数据结构之队列,感兴趣的朋友跟随小编一起学习吧
    2017-04-04
  • Java并发编程中的ReentrantLock详解

    Java并发编程中的ReentrantLock详解

    这篇文章主要介绍了Java并发编程中的ReentrantLock详解,从Java 5 开始,引入了一个高级的处理并发的java.util.concurrent包,它提供了大量更高级的并发功能,能大大简化多线程程序的编写,需要的朋友可以参考下
    2023-11-11
  • 基于spring+quartz的分布式定时任务框架实现

    基于spring+quartz的分布式定时任务框架实现

    在Spring中的定时任务功能,最好的办法当然是使用Quartz来实现。这篇文章主要介绍了基于spring+quartz的分布式定时任务框架实现,有兴趣的可以了解一下。
    2017-01-01
  • SpringBoot个性化启动Banner设置方法解析

    SpringBoot个性化启动Banner设置方法解析

    这篇文章主要介绍了SpringBoot个性化启动Banner设置方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Java实现权重随机算法详解

    Java实现权重随机算法详解

    平时,经常会遇到权重随机算法,从不同权重的N个元素中随机选择一个,并使得总体选择结果是按照权重分布的。本文就详细来介绍如何实现,感兴趣的可以了解一下
    2021-07-07
  • Java-lambda表达式入门看这一篇就够了

    Java-lambda表达式入门看这一篇就够了

    lambda表达式最简单的作用就是用于简化创建匿名内部类对象,Lambda表达式是一个可传递的代码块,可以在以后执行一次或多次,下面通过本文给大家介绍Java-lambda表达式入门教程,感兴趣的朋友一起看看吧
    2021-05-05
  • java集合类源码分析之Set详解

    java集合类源码分析之Set详解

    下面小编就为大家带来一篇java集合类源码分析之Set详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10

最新评论