Leetcode_day01_88合并两个有序数组

Leetcode_day01_88合并两个有序数组

题目描述:

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 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 中。

核心知识点:数组,排序,双指针
解法一:先将数组nums2放入到数组nums1中,然后再排序

class Solution{
	public void merge(int [] nums1, int m, int [] nums2, int n){
		for(int i = 0;i != n; ++i){
			nums1[m + i] = nums2[i];
		}
		Arrays.sort(nums1);
	}
}
		

时间复杂度:O((m+n)log⁡(m+n)) 【快排】
空间复杂度:O(log⁡(m+n)) 【快排】
在这里插入图片描述

解法二:双指针
这一方法将两个数组看作队列,每次从两个数组头部取出比较小的数字放到结果中。

class Solution{
	public void merge(int [] nums1, int m, int [] nums2, int n){
		//定义两个指针
		int p1 = 0 ,p2 = 0;
		//存放排好序数据的数组
		int [] sorted = new int [m + n];
		int cur;
		while(p1 < m || p2 < n){
			// p1 == m nums1没了
			if(p1 == m){
				cur = nums2[p2++];
			// p2 == n nums2没了
			} else if(p2 == n){
				cur = nums1[p1++];
			} else if(nums1[p1] < nums2[p2]){
				cur = nums1[p1++];
			} else {
				cur = nums2[p2++];
			}
			sorted[p1 + p2 - 1] = cur;
		}
		for (int i = 0; i != m + n; ++i){
			nums1[i] = sorted[i];
		}
	}
}
		

时间复杂度:O(m+n)。
指针最多移动M+N次
空间复杂度:O(m+n)。
创建一个中间数组
在这里插入图片描述

解法三:逆向双指针
在解法三的基础上,原地移动,减少空间复杂度的占用。从后向前一次遍历数组,将大的值移动到nums1中的后边。
任意时刻nums1中填入了 (m-p1-1)+(n-p2-1)=m+n-p1-p2-2,nums1中剩余m+n-p1-1
m+n-p1-1 - (m+n-p1-p2-2) = p2 + 1 > 0 因此不会出现覆盖。

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
    	//定义指针
        int p1 = m - 1, p2 = n - 1;
        //从tail开始依次向前添加元素
        int tail = m + n - 1;
        int cur;
        while (p1 >= 0 || p2 >= 0) {
        	//nums1结束
            if (p1 == -1) {
                cur = nums2[p2--];
            //nums2结束
            } else if (p2 == -1) {
                cur = nums1[p1--];
            } else if (nums1[p1] > nums2[p2]) {
                cur = nums1[p1--];
            } else {
                cur = nums2[p2--];
            }
            nums1[tail--] = cur;
        }
    }
}

时间复杂度:O(m+n)
空间复杂度:O(1).
在这里插入图片描述
可以看到两种方法的内存占用并没有很大的差距。
chatgbt临时生成了程序来测试一下内存的占用情况:

	public class MergeTest {
	    public static void main(String[] args) {
	        int[] nums1 = {1, 2, 3, 0, 0, 0};
	        int m = 3;
	        int[] nums2 = {2, 5, 6};
	        int n = 3;
	        Runtime runtime = Runtime.getRuntime();
	        
	        // 获取初始内存使用情况
	        long memoryBefore = runtime.totalMemory() - runtime.freeMemory();
	        System.out.println("Initial Memory Usage: " + memoryBefore + " bytes");
	
	        // 在这里运行你的代码,例如调用代码1的merge方法
	        merge1(nums1, m, nums2, n);     
	        // 获取代码执行后的内存使用情况
	        long memoryAfter = runtime.totalMemory() - runtime.freeMemory();
	
	        // 计算内存差异
	        long memoryUsed = memoryAfter - memoryBefore;
	        System.out.println("merge1 Memory Used: " + memoryUsed + " bytes");
	
	        Runtime runtime2 = Runtime.getRuntime();
	        
	        // 获取初始内存使用情况
	        long memoryBefore2 = runtime2.totalMemory() - runtime2.freeMemory();
	        // System.out.println("Initial Memory Usage: " + memoryBefore2 + " bytes");
	
	        // 在这里运行你的代码,例如调用代码1的merge方法
	        merge2(nums1, m, nums2, n);
	        // 获取代码执行后的内存使用情况
	        long memoryAfter2 = runtime2.totalMemory() - runtime2.freeMemory();
	        System.out.println("merge2 Memory Usage After Execution: " + memoryAfter2 + " bytes");
	
	        // 计算内存差异
	        long memoryUsed2 = memoryAfter2 - memoryBefore2;
	        System.out.println("Memory Used: " + memoryUsed + " bytes");
	    }
	    public static void merge1(int [] nums1, int m, int [] nums2, int n){
			//定义两个指针
			int p1 = 0 ,p2 = 0;
			//存放排好序数据的数组
			int [] sorted = new int [m + n];
			int cur;
			while(p1 < m || p2 < n){
				// p1 == m nums1没了
				if(p1 == m){
					cur = nums2[p2++];
				// p2 == n nums2没了
				} else if(p2 == n){
					cur = nums1[p1++];
				} else if(nums1[p1] < nums2[p2]){
					cur = nums1[p1++];
				} else {
					cur = nums2[p2++];
				}
				sorted[p1 + p2 - 1] = cur;
			}
			for (int i = 0; i != m + n; ++i){
				nums1[i] = sorted[i];
			}
		}
	    public static void merge2(int[] nums1, int m, int[] nums2, int n) {
	    	//定义指针
	        int p1 = m - 1, p2 = n - 1;
	        //从tail开始依次向前添加元素
	        int tail = m + n - 1;
	        int cur;
	        while (p1 >= 0 || p2 >= 0) {
	        	//nums1结束
	            if (p1 == -1) {
	                cur = nums2[p2--];
	            //nums2结束
	            } else if (p2 == -1) {
	                cur = nums1[p1--];
	            } else if (nums1[p1] > nums2[p2]) {
	                cur = nums1[p1--];
	            } else {
	                cur = nums2[p2--];
	            }
	            nums1[tail--] = cur;
	        }
	    }
 
}

结果:变化太小,看不出来
在这里插入图片描述
有点晚了,有时间再探索一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/294850.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 2:两数相加

一、题目描述 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个…

华为交换机ETH-TRUNK链路聚合lacp模式与手工模式

SW1配置如下 vlan batch 10interface Eth-Trunk1port link-type trunkport trunk allow-pass vlan 10mode lacp-static #手工模式删除改行max active-linknumber 2 #手工模式删除改行trunkport GigabitEthernet 0/0/1 to 0/0/2#配置为主设备&#xff08;修改优先级&…

下载知虾数据分析软件:优化店铺运营、提高转化率的利器

在如今竞争激烈的电商市场中&#xff0c;对销售数据、流量以及买家行为等关键指标的监控和分析至关重要。Shopee平台为卖家提供了一个内置的在线数据分析工具——“Shopee Analytics”&#xff08;知虾分析&#xff09;&#xff0c;让卖家能够轻松实现对店铺运营的优化、提高转…

通过XML您可以发明自己的标签

XML 仅仅是纯文本 XML 没什么特别的。它仅仅是纯文本而已。有能力处理纯文本的软件都可以处理 XML。 不过&#xff0c;能够读懂 XML 的应用程序可以有针对性地处理 XML 的标签。标签的功能性意义依赖于应用程序的特性。 通过XML您可以发明自己的标签 在之前的例中的标签没有…

bootstrap5实现家具品牌商城网站Furniq(电商通用)

一、需求分析 家具品牌宣传网站是指用于宣传和推广家具品牌的网站。它的功能主要包括以下几个方面&#xff1a; 品牌介绍&#xff1a;家具品牌宣传网站通常会提供关于品牌的背景信息&#xff0c;包括品牌的历史、核心价值观、设计理念等。这些信息可以帮助消费者了解品牌的定位…

JavaScript怎么输出变量的值到控制台

2024年1月5日&#xff0c;周五晚上 通过console.log可以输出变量的值到控制台 let number 100;console.log(number);

风靡全网的Jmeter+ant+jenkins接口自动化测试框架

大致思路&#xff1a;Jmeter可以做接口测试&#xff0c;也能做压力测试&#xff0c;而且是开源软件&#xff1b;Ant是基于Java的构建工具&#xff0c;完成脚本执行并收集结果生成报告&#xff0c;可以跨平台&#xff0c;Jenkins是持续集成工具。将这三者结合起来可以搭建一套We…

如何利用SD-WAN优化企业访问Salesforce的体验?

在这个数字化时代&#xff0c;客户关系管理&#xff08;CRM&#xff09;应用如 Salesforce &#xff0c;已经成为企业运营的重要部分。然而&#xff0c;许多企业在使用 Salesforce 时常遇到页面加载缓慢、甚至完全无法访问等问题&#xff0c;严重影响了他们的工作效率和用户体验…

卷积神经网络|制作自己的Dataset(最终版)

​之前文章已经实现了一个自定义的类&#xff0c;制定了自己的数据集。其实&#xff0c;细看代码&#xff0c;可传入的参数过多&#xff0c;有些简单问题复杂化&#xff0c;实现上不是那么简洁。 既然是自己定义的数据集&#xff0c;那么许多功能是自己写好的&#xff0c;如何…

设计模式——最全梳理,最好理解

新年献礼&#xff01; 设计模式呕心梳理 创建型模式 单例模式&#xff08;Singleton Pattern&#xff09;https://blog.csdn.net/qq_34869143/article/details/134874044 整理中... 结构型模式 代理模式&#xff08;Proxy Pattern&#xff09;https://blog.csdn.net/qq_34…

在Fiber中处理请求和响应

掌握GoLang Fiber中请求和响应管理的艺术&#xff0c;以实现高效的Web开发 在Web开发领域&#xff0c;有效地处理请求和响应是构建既用户友好又高效的Web应用的基石。该过程涉及管理传入的HTTP请求、解析数据和参数、构建适当的响应、处理不同的响应类型以及优雅地处理错误。对…

【unity】Obi插件架构组成(参数详细解释)——解算器四面板设置、三种更新器、参与者介绍

文章目录 一、架构&#xff08;Architecture&#xff09;1.1 Obi解算器&#xff08;ObiSolver&#xff09;1.2 ObiUpdater1.3 ObiActorBlueprint1.4 Obi参与者&#xff08;ObiActor&#xff0c;如ObiRope等&#xff09; 二、Obi解算器&#xff08;ObiSolver&#xff09;2.1 解算…

解决:Microsoft Visual C++ 14.0 is required.

Microsoft Visual C 14.0 is required. Get it with “Microsoft Visual C Build Tools 当我们安装绝大部分python包的时候可以通过pip install 或者 conda install解决&#xff0c;但是任然有些包是安装不了的&#xff0c;比如我的就是在安装pyqt5的时候报Building wheel for…

51单片机之按键和数码管

51单片机之按键和数码管 ✍前言&#xff1a;♐独立按键&#x1f600;独立按键的原理&#x1f600;软件实现按键控制LED灯的亮灭 ♐数码管&#x1f60a;数码管显示数字或者字母的原理&#x1f409;共阳极数码管&#x1f409;共阴极极数码管&#x1f409;4位1体数码管 &#x1f6…

二叉搜索树与双向链表

解题思路一&#xff1a; /** public class TreeNode {int val 0;TreeNode left null;TreeNode right null;public TreeNode(int val) {this.val val;} } */ // 一定要用自己的理解真正弄出来才行&#xff0c;否则没有用&#xff01; // 再次提醒&#xff0c;计算机这种工科…

【计算机算法设计与分析】n皇后问题(C++_回溯法)

文章目录 题目描述测试样例算法原理算法实现参考资料 题目描述 在nxn格的棋盘上放置彼此不受攻击的n格皇后。按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在nxn格的棋盘上放置n个皇后&#xff0c;任何2个皇后不放在同…

三款推荐的 FTP 工具

&#x1f947; 版权: 本文由【墨理学AI】原创、在CSDN首发、各位大佬、敬请查阅&#x1f389; 声明: 作为全网 AI 领域 干货最多的博主之一&#xff0c;❤️ 不负光阴不负卿 ❤️ 文章目录 三款推荐的 FTP 工具filezillawinscpFinalShell SSHXftp❤️ 人生苦短&#xff0c; 欢迎…

linux 系统 kill 指令笔记

kill 名称 kill - send a signal to a process 向指定的线程或进程发送信号 描述 The default signal for kill is TERM. Use -l or -L to list availablesignals. Particularly useful signals include HUP, INT, KILL, STOP,CONT, and 0. Alternate signals …

啊哈c语言——逻辑挑战8:验证哥德巴赫猜想

上面这封书信是普鲁士数学家哥德巴赫在1742年6月7日写给瑞士数学家欧拉的&#xff0c;哥德巴赫在书信中提出了“任一大于2的整数都可以写成3个质数之和”的猜想。当时&#xff0c;哥德巴赫遵照的是“1也是素数”的约定。现今&#xff0c;数学界已经不使用这个约定了。哥德巴赫原…

新品牌在小红书上宣传推广怎么做?

对于新品牌来说&#xff0c;如何在小红书进行有效的宣传推广&#xff0c;成为了一大挑战。本文伯乐网络传媒将为你揭秘新品牌在小红书上的宣传策略&#xff0c;助你牢牢抓住用户流量&#xff0c;提升品牌知名度。 小红书作为一款以内容为核心的社交电商平台&#xff0c;具有极高…
最新文章