算法小白 Leetcode刷题篇

Posted 雨宙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法小白 Leetcode刷题篇相关的知识,希望对你有一定的参考价值。

合并两个有序数组

题目指路

题目描述:
给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。

初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。你可以假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2 的元素。

示例 1:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]

示例 2:
输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]

思路一:
直接将nums2数组中的数连接到nums1数组的后面,再对新形成的数组进行排序,可以先摸鱼一下,直接调用sort函数进行排序。

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

思路二:
另外再创建一个数组,使新建的数组等于nums1的前m个数字,设置两个指针p1和p2,分别指向两个数组的第一个元素,在满足循环条件的前提下,当p1指向的元素小于等于p2指向的元素时,将p1所指的元素赋值到nums1数组的对应位置上,当p1指向的元素大于p2指向的元素时,将p2所指的元素赋值到nums1数组的对应位置上,当跳出循环时,nums数组的后几位可能还没有进行赋值,此时将没有遍历完的数组部分赋值到nums1数组的后几位上。

class Solution 
    public void merge(int[] nums1, int m, int[] nums2, int n) 
        int p1=0;
        int p2=0;
        int count=0;
        int [] array = new int[m];
        System.arraycopy(nums1, 0, array, 0, m);
        while((p1<m)&&(p2<n))
            if(array[p1]<=nums2[p2])
                nums1[count]=array[p1];
                p1++;
            else if(array[p1]>nums2[p2])
                nums1[count]=nums2[p2];
                p2++;
            
            count++;
        
        if(p1<m)
            for(int i=p1;i<m;i++)
                nums1[count]=array[i];
                count++;
            
        
        if(p2<n)
            for(int i=p2;i<n;i++)
                nums1[count]=nums2[i];
                count++;
            
        
    

唯一的不足就是有点占用空间。

思路三:
参考了答案之后的思路,指针从最后开始向前走,这样就可以不用另外申请一块空间保存nums1数组,可以有效地节省空间。
具体思路如下,设置三个指针,p2指向nums1数组的末尾,p2指向nums2数组的末尾,p1指向nums1有效数组的末尾(不为0的最后一位),在p3指针不断向前移动的过程中,有以下几种情况:
1.p1为-1,此时p1指针已经移动到nums1的最左端,接下来只需要将nums2数组中的剩余数字放到nums1数组中即可。
2.p2为-1,此时p2指针已经移动到nums2的最左端,接下来只需要将nums1数组中的剩余数字放到nums1数组中即可。
3.p1指针指向的数字比p2指针指向的数字大(或等于),将p1指针指向的数字移动到p3指针指向的位置,p1和p3向左移动。
4.p1指针指向的数字比p2指针指向的数字小,将p2指针指向的数字移动到p3指针指向的位置,p2和p3向左移动。

class Solution 
    public void merge(int[] nums1, int m, int[] nums2, int n) 
        int p1=m-1;
        int p2=n-1;
        int p3=m+n-1;
        while(p3>=0)
            if(p1==-1)
                nums1[p3]=nums2[p2];
                p3--;
                p2--;
            else if(p2==-1)
                nums1[p3]=nums1[p1];
                p3--;
                p1--;
            else if(nums1[p1]>=nums2[p2])
                nums1[p3]=nums1[p1];
                p3--;
                p1--;
            else if(nums1[p1]<nums2[p2])
                nums1[p3]=nums2[p2];
                p3--;
                p2--;
            
        
    

以上是关于算法小白 Leetcode刷题篇的主要内容,如果未能解决你的问题,请参考以下文章

贪心算法刷题篇 分发饼干与摆动序列

LeetCode按照怎样的顺序来刷题比较好?

二叉树刷题篇层序遍历

数字出现次数问题刷题篇——2

二叉树刷题篇前中后序遍历的递归与迭代算法

二叉树刷题篇(10) 二叉搜索树