首页 > 其他分享 >3623、合并两个有序数组

3623、合并两个有序数组

时间:2023-02-14 14:34:08浏览次数:38  
标签:数组 nums2Index int 3623 合并 有序 new nums1 nums2

给你两个按 非递减顺序 排列的整数数组 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 中。


提示:


nums1.length == m + n

nums2.length == n

0 <= m, n <= 200

1 <= m + n <= 200

-109 <= nums1[i], nums2[j] <= 109


进阶:你可以设计实现一个时间复杂度为 O(m + n) 的算法解决此问题吗?


来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/merge-sorted-array

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package cn.fansunion.leecode.linkedlist;

/**

* 88. 合并两个有序数组 <br/>给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。

*

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

*

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

*

* 来源:力扣(LeetCode) 链接:力扣 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

*

* @author [email protected]

*

* 2022-2-23

*/

public class MergeSortedArray {

/* 示例 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 <= nums1[i], nums2[j] <= 109*/

/**

* 思路:目标是把nums2按照顺序插入到nums1,从后向前比较插入;双指针,效率高;<br/>

* 如果nums2有剩余的没插入,需要单独再插入<br/>

* 如果nums1有剩余的没插入,不需要处理,特征是处理nums2,nums2没处理的自然就有序的<br/>

* 官方算法学名:“逆向双指针”。因为算法题经常都是各种“奇思妙想”,“诡计”,突然想到:就是从后向前容易点,逐步替换“0”的过程

* 这道题的“合并数组”,又是有特定要求的;常见的合并数组:nums1+nums2,可以直接new一个nums3,正向遍历nums1和nums2

*

*

* @param nums1

* @param m

* @param nums2

* @param n

*/

public void merge(int[] nums1, int m, int[] nums2, int n) {

int nums1Index = m - 1;

int nums2Index = n - 1;

int curIndex = m + n - 1;

while (nums1Index >= 0 && nums2Index >= 0) {

if (nums1[nums1Index]<= nums2[nums2Index]) {

nums1[curIndex] = nums2[nums2Index];

nums2Index--;

curIndex--;

} else {

nums1[curIndex] = nums1[nums1Index];

nums1Index--;

curIndex--;

}

}

// nums1提前往后挪了,nums2还有剩下的

// 这种题目,边界值的情况经常有,一次性想不全,必须得构造很多测试用例额

while (nums2Index >= 0) {

nums1[nums2Index] = nums2[nums2Index];

nums2Index--;

}

}

/**

* 合并两个有序数组(笨办法),结果还不对<br/>

* [-1,0,0,3,3,3,0,0,0] 6,[1,2,2] 3;输出:[1,2,2,-1,0,0,3,3,3],预期:[-1,0,0,1,2,2,3,3,3]

*

* @param nums1

* nums1 = [1,2,3,0,0,0]

* @param m

* 3 nums2 = [2,5,6]

* @param nums2

* 3

* @param n

* 3 输出:[1,2,2,3,5,6] 解释:需要合并 [1,2,3] 和 [2,5,6] 。

*/

public void mergeStupidAndError(int[] nums1, int m, int[] nums2, int n) {

// 遍历需要插入的若干数字

for (int nums2Index = 0; nums2Index < n; nums2Index++) {

// 插入1个数字到目标数组里

mergeIntoNums(nums2[nums2Index], nums1);

}

}

// 插入1个数字到目标数组里

private void mergeIntoNums(int newNum, int[] nums) {

// 先找插入位置

int insertIndex = 0;

for (int i = 0; i < nums.length; i++) {

if (nums[i] <= 0 || newNum < nums[i]) {

insertIndex = i;

break;

}

insertIndex++;

}

// 通过2个临时变量的辅助,插入,效果:后面的数字都往后移一位

int cur = newNum;

int next = 0;

for (int index = insertIndex; index < nums.length; index++) {

next = nums[index];

nums[index] = cur;

cur = next;

}

}

/**

* 另外一种形式的合并数组,允许构造新的merge数组并返回,稍微简单点

*

* @param nums1

* @param nums2

* @return

*/

public int[] mergeWithReturn(int[] nums1, int[] nums2) {

int[] nums = new int[nums1.length + nums2.length];

int nums1Index = 0;

int nums2Index = 0;

int curIndex = 0;

// 双指针

while (nums1Index < nums1.length && nums2Index < nums2.length) {

if (nums1[nums1Index] <= nums2[nums2Index]) {

nums[curIndex] = nums1[nums1Index];

nums1Index++;

} else {

nums[curIndex] = nums2[nums2Index];

nums2Index++;

}

curIndex++;

}

// num1有剩余的

while (nums1Index < nums1.length) {

nums[curIndex] = nums1[nums1Index];

nums1Index++;

curIndex++;

}

// nums2有剩余的

while (nums2Index < nums2.length) {

nums[curIndex] = nums2[nums2Index];

nums2Index++;

curIndex++;

}

return nums;

}

}
package test.leecode.linkedlist;

import org.junit.Assert;

import org.junit.Test;

import cn.fansunion.leecode.linkedlist.MergeSortedArray;

/**

* @author [email protected]

*

* 2022-2-23

*/

public class MergeSortedArrayTest {

@Test

public void test() {

MergeSortedArray test = new MergeSortedArray();

// test2

int[] nums3 = new int[] {2, 3, 5, 0, 0, 0, 0, 0};

int[] nums4 = new int[] {1, 4, 5, 6, 9};

test.merge(nums3, 3, nums4, 5);

Assert.assertArrayEquals(new int[] {1, 2, 3, 4, 5, 5, 6, 9}, nums3);

// test1

int[] nums1 = new int[] {1, 2, 3, 0, 0, 0};

int[] nums2 = new int[] {2, 5, 6};

test.merge(nums1, 3, nums2, 3);

Assert.assertArrayEquals(new int[] {1, 2, 2, 3, 5, 6}, nums1);

// test3

int[] nums5 = new int[] {3, 3, 3, 3, 0, 0, 0, 0};

int[] nums6 = new int[] {1, 1, 2, 2};

test.merge(nums5, 4, nums6, 4);

Assert.assertArrayEquals(new int[] {1, 1, 2, 2, 3, 3, 3, 3}, nums5);

// test4

int[] nums7 = new int[] {1, 1, 2, 3, 0, 0, 0, 0};

int[] nums8 = new int[] {4, 5, 6, 7};

test.merge(nums7, 4, nums8, 4);

Assert.assertArrayEquals(new int[] {1, 1, 2, 3, 4, 5, 6, 7}, nums7);

}

@Test

public void testMergeWithReturn() {

MergeSortedArray test = new MergeSortedArray();

// test2

int[] nums3 = new int[] {2, 3, 5};

int[] nums4 = new int[] {1, 4, 5, 6, 9};

int[] test2 = test.mergeWithReturn(nums3, nums4);

Assert.assertArrayEquals(new int[] {1, 2, 3, 4, 5, 5, 6, 9}, test2);

// test1

int[] nums1 = new int[] {1, 2, 3};

int[] nums2 = new int[] {2, 5, 6};

int[] test1 = test.mergeWithReturn(nums1, nums2);

Assert.assertArrayEquals(new int[] {1, 2, 2, 3, 5, 6}, test1);

// test3

int[] nums5 = new int[] {3, 3, 3, 3};

int[] nums6 = new int[] {1, 1, 2, 2};

int[] test3 = test.mergeWithReturn(nums5, nums6);

Assert.assertArrayEquals(new int[] {1, 1, 2, 2, 3, 3, 3, 3}, test3);

// test4

int[] nums7 = new int[] {1, 1, 2, 3};

int[] nums8 = new int[] {4, 5, 6, 7};

int[] test4 = test.mergeWithReturn(nums7, nums8);

Assert.assertArrayEquals(new int[] {1, 1, 2, 3, 4, 5, 6, 7}, test4);

}

// mergeStupid

public static void main(String[] args) {

// test1

int[] nums1 = new int[] {1, 2, 3, 0, 0, 0};

int[] nums2 = new int[] {2, 5, 6};

MergeSortedArray msa = new MergeSortedArray();

msa.mergeStupidAndError(nums1, 3, nums2, 3);

for (int num : nums1) {

System.out.print(num);

}

System.out.println();

// test2

int[] nums3 = new int[] {2, 3, 5, 0, 0, 0, 0, 0};

int[] nums4 = new int[] {1, 4, 5, 6, 9};

MergeSortedArray msa2 = new MergeSortedArray();

msa2.mergeStupidAndError(nums3, 3, nums4, 5);

for (int num : nums3) {

System.out.print(num);

}

}

}

标签:数组,nums2Index,int,3623,合并,有序,new,nums1,nums2
From: https://blog.51cto.com/fansunion/6056791

相关文章

  • 3597、找到所有数组中消失的数字
    给你一个含n个整数的数组nums,其中nums[i]在区间[1,n]内。请你找出所有在[1,n]范围内但没有出现在nums中的数字,并以数组的形式返回结果。示例1:输入:nums=[4......
  • 3606、数组的度
    给定一个非空且只包含非负数的整数数组nums,数组的度的定义是指数组里任一元素出现频数的最大值。你的任务是在nums中找到与nums拥有相同大小的度的最短连续子数组,返......
  • 二维数组中的查找
    问题:矩阵从左至右、从上至下非递减顺序,查找target是否在数组中剑指Offer04.二维数组中的查找-力扣(LeetCode)方法一:标志数flag:选择左下角或者右上角为标志数;选择左下......
  • 顺序表应用5:有序顺序表归并(SDUT 3329)
    ProblemDescription已知顺序表A与B是两个有序的顺序表,其中存放的数据元素皆为普通整型,将A与B表归并为C表,要求C表包含了A、B表里所有元素,并且C表仍然保持有序。Input......
  • 顺序表应用6:有序顺序表查询(SDUT 3330)
    ProblemDescription顺序表内按照由小到大的次序存放着n个互不相同的整数,任意输入一个整数,判断该整数在顺序表中是否存在。如果在顺序表中存在该整数,输出其在表中的序......
  • 每日一题.截断数组
    先特判,显而易见数组的前缀和必须是3的倍数,要不然分不成三份。然后就是遍历前缀和让它和1/3总和和2/3总和比,显然当第二个1/3也成立的时候就可以停止遍历,然后可以继续遍历或......
  • VBA遍历数组的2种方式
     1.情景展示VBA编程,如何对数组进行遍历?2.解决方案方式一:使用for循环Sub遍历数组1()'声明一个变量DimArrAsVariant'声明一个数字变量DimiAs......
  • C语言填空:数组a b c,c中元素包括a,但不在b中
    #include<stdio.h>//数组a中有8个不相等的元素,b中有5个不相等的元素,数组c中包含那些a中但不在b中的元素,并输出数组c各元素的值main(){inta[8],b[5],i,j,count;......
  • 88. 合并两个有序数组
    给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。请你 合并 nums2 到 nums1 中,使合......
  • halcon 伪二维数组
    没找到二维数组的方式,使用伪二维数组(其实是一维向量)RegionAlignment_ROI1:=[724.615,1571.03,841.724,1903]RegionText_ROI1:=[986,1436,1282,1834]row1s_pos_RO......