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++ 序列递增最小交换次数的资料请关注脚本之家其它相关文章!

相关文章

  • java开发主流定时任务解决方案全横评详解

    java开发主流定时任务解决方案全横评详解

    这篇文章主要为大家介绍了java开发主流定时任务解决方案全横评详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • springboot配置http跳转https的过程

    springboot配置http跳转https的过程

    SSL是为网络通信提供安全以及保证数据完整性的的一种安全协议,SSL在网络传输层对网络连接进行加密,这篇文章主要介绍了springboot配置http跳转https的过程,需要的朋友可以参考下
    2023-04-04
  • Spring @Cacheable注解类内部调用失效的解决方案

    Spring @Cacheable注解类内部调用失效的解决方案

    这篇文章主要介绍了Spring @Cacheable注解类内部调用失效的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • springboot2自动加载sql文件的实现

    springboot2自动加载sql文件的实现

    本文主要介绍了springboot2自动加载sql文件的实现,通过配置文件或注解的方式,我们可以轻松地将SQL语句映射到数据库中,实现自动加载,感兴趣的可以了解一下
    2023-11-11
  • @DynamicUpdate //自动更新updatetime的问题

    @DynamicUpdate //自动更新updatetime的问题

    这篇文章主要介绍了@DynamicUpdate //自动更新updatetime的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • 基数排序简介及Java语言实现

    基数排序简介及Java语言实现

    这篇文章主要介绍了基数排序简介及Java语言实现,涉及基数排序的基本思想简单介绍和桶排序的分析,以及基数排序的Java实现,具有一定借鉴价值,需要的朋友可以参考下。
    2017-11-11
  • Java for循环的几种用法分析

    Java for循环的几种用法分析

    本篇文章小编为大家介绍,Java for循环的几种用法分析。需要的朋友参考下
    2013-04-04
  • 一文教你搞懂SpringBoot自定义拦截器的思路

    一文教你搞懂SpringBoot自定义拦截器的思路

    在开发中,都离不开拦截器的使用,比如说在开发登录功能时,实现权限管理功能时等,这篇文章主要带大家使用SpringBoot梳理自定义拦截器的思路,需要的可以参考一下
    2023-08-08
  • Spring Cloud Stream简单用法

    Spring Cloud Stream简单用法

    Spring cloud stream是为构建微服务消息驱动而产生的一种框架。Spring Cloud Stream基于Spring boot的基础上,可创建独立的、生产级别的Spring应用,并采用Spring Integration来连接消息中间件提供消息事件驱动,一起看看吧
    2021-07-07
  • Spring Cache的使用示例详解

    Spring Cache的使用示例详解

    SpringCache是构建在SpringContext基础上的缓存实现,提供了多种缓存注解,如@Cachable、@CacheEvict、@CachePut等,本文通过实例代码介绍了Spring Cache的使用,感兴趣的朋友一起看看吧
    2025-01-01

最新评论