算法leetcode|88. 合并两个有序数组(rust重拳出击)


文章目录


88. 合并两个有序数组:

给你两个按 非递减顺序 排列的整数数组 nums1nums2,另有两个整数 mn ,分别表示 nums1nums2 中的元素数目。

请你 合并 nums2nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意 :最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n

样例 1:

复制代码
输入:
	
	nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
	
输出:
	
	[1,2,2,3,5,6]
	
解释:

	需要合并 [1,2,3] 和 [2,5,6] 。
	合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。

样例 2:

复制代码
输入:
	
	nums1 = [1], m = 1, nums2 = [], n = 0
	
输出:
	
	[1]
	
解释:

	需要合并 [1] 和 [] 。
	合并结果是 [1] 。

样例 3:

复制代码
输入:
	
	nums1 = [0], m = 0, nums2 = [1], n = 1
	
输出:
	
	[1]
	
解释:

	需要合并的数组是 [] 和 [1] 。
	合并结果是 [1] 。
	注意,因为 m = 0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。

提示:

  • nums1.length == m + n
  • nums2.length == n
  • 0 <= m, n <= 200
  • 1 <= m + n <= 200
  • -109 <= nums1i, nums2j <= 109

分析:

  • 面对这道算法题目,二当家的再次陷入了沉思。
  • 如果直接就把 nums2 放到 num1 后面,然后再对合并后的 num1 进行排序,时间复杂度是 O((m+n)log(m+n)) ,不是很理想,完全没有使用数组本身有序这个便利条件。
  • 对排序算法熟悉的话,可以想到归并排序算法,其中将两个有序部分合并到一起正好就是我们要做的,但是这样需要额外的空间,而且最后还需要把结果再拷贝回 num1
  • 稍稍做下优化,前面我们之所以要使用额外空间就是因为处理过程中会把还没有处理的 num1 部分覆盖,我们可以逆向遍历处理,因为最开始 num1 的后半部分是空的,所以我们就选取较大值放到末尾,依次处理,而且只要将 nums2 处理完毕就可以停止了,因为 num1 的剩余部分已经是有序的,这样不需要额外空间,而且时间复杂度仅仅是 O(m+n) ,非常不错。

题解:

rust:

rust 复制代码
impl Solution {
    pub fn merge(nums1: &mut Vec<i32>, m: i32, nums2: &mut Vec<i32>, n: i32) {
        let (mut l1, mut l2, mut l) = (m - 1, n - 1, m as usize + n as usize - 1);
        while l2 >= 0 {
            if l1 >= 0 && nums1[l1 as usize] > nums2[l2 as usize] {
                nums1[l] = nums1[l1 as usize];
                l1 -= 1;
            } else {
                nums1[l] = nums2[l2 as usize];
                l2 -= 1;
            }
            l -= 1;
        }
    }
}

go:

go 复制代码
func merge(nums1 []int, m int, nums2 []int, n int)  {
    l1, l2, l := m-1, n-1, m+n-1
	for l2 >= 0 {
		if l1 >= 0 && nums1[l1] > nums2[l2] {
			nums1[l] = nums1[l1]
			l1--
		} else {
			nums1[l] = nums2[l2]
			l2--
		}
		l--
	}
}

c++:

cpp 复制代码
class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int l1 = m - 1;
        int l2 = n - 1;
        int l = m + n - 1;
        while (l2 >= 0) {
            nums1[l--] = l1 >= 0 && nums1[l1] > nums2[l2] ? nums1[l1--] : nums2[l2--];
        }
    }
};

python:

python 复制代码
class Solution:
    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        """
        Do not return anything, modify nums1 in-place instead.
        """
        l1, l2, l = m - 1, n - 1, m + n - 1
        while l2 >= 0:
            if l1 >= 0 and nums1[l1] > nums2[l2]:
                nums1[l] = nums1[l1]
                l1 -= 1
            else:
                nums1[l] = nums2[l2]
                l2 -= 1
            l -= 1

java:

java 复制代码
class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int l1 = m - 1;
        int l2 = n - 1;
        int l  = m + n - 1;
        while (l2 >= 0) {
            nums1[l--] = l1 >= 0 && nums1[l1] > nums2[l2] ? nums1[l1--] : nums2[l2--];
        }
    }
}

非常感谢你阅读本文~

欢迎【点赞】【收藏】【评论】三连走一波~

放弃不难,但坚持一定很酷~

希望我们大家都能每天进步一点点~

本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~


相关推荐
IT探索4 分钟前
Linux 查找文件指令总结
linux·算法
zephyr0523 分钟前
数据结构-并查集
数据结构
Lumos1861 小时前
51单片机从零到实战(完结)——后续学习路线建议
算法
稚南城才子,乌衣巷风流1 小时前
DFS序详解:原理、应用与实现
算法·深度优先·图论
稚南城才子,乌衣巷风流1 小时前
动态树(Dynamic Tree)数据结构详解
数据结构·算法
止语Lab1 小时前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活1 小时前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
程序员天天困1 小时前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn1 小时前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
用户298698530141 小时前
Python 实现 Excel 与 Markdown 互转的实用指南
后端·python·excel