CodeTop015 合并两个有序数组

这篇博客介绍了如何使用双指针方法合并两个有序数组,并探讨了在合并过程中如何避免元素重复。作者提供了三种不同的实现方式,包括直接排序、创建新数组再复制以及倒序双指针法。此外,还提出了一个进阶问题,即在合并链表时如何同时去重,同样使用双指针解决。通过这些实例,读者可以深入理解双指针在数组和链表操作中的应用。
摘要由CSDN通过智能技术生成

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

  • 思路一:直接将nums2全部放到num1的尾部 然后直接排序(没什么技术含量)
  • 思路二:双指针 然后开创一个新数组,将排序结果放到新数组中,最后再移到nums1中
  • 思路三:双指针 但是是倒序的 将数组按从大到小存放在nums1的末尾 这样可以保证直接在nums1中进行操作而不会覆盖前面的nums1中的元素

进阶问题:合并链表并去重,还是利用双指针,只是在nums1[p1]==nums2[p2]条件时,让p1指针直接往后移动即可

public class Solution015 {
    public static void main(String[] args) {
        int[] nums1 = new int[]{1,2,3,0,0,0},num2 = new int[]{2,5,6};
        //merge3(nums1,3,num2,3);
        //System.out.println(Arrays.toString(nums1));
        //去重的情况
        int[] ans = merge4(nums1, 3, num2, 3);
        System.out.println(Arrays.toString(ans));
    }

    //方式一:直接将nums2全部放到num1的尾部 然后直接排序(没什么技术含量)
    public static 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中
    public static void merge2(int[] nums1,int m,int[] nums2,int n){
        int p1 = 0,p2 = 0;
        int[] sort = new int[m+n];
        int temp;
        while(p1<m||p2<n){
            if (p1==m){
                temp = nums2[p2];
                p2++;
            }else if (p2==n){
                temp = nums1[p1];
                p1++;
            }else if(nums1[p1]<=nums2[p2]){
                temp = nums1[p1];
                p1++;
            }else{
                temp = nums2[p2];
                p2++;
            }

            sort[p1+p2-1] = temp;
        }

        nums1 = Arrays.copyOf(sort,sort.length);
    }

    //方式三:双指针 但是是倒序的 这样可以保证直接在nums1中进行操作而不会覆盖前面的nums1中的元素(但是这个时候双指针的排序是倒着从大到小排)
    public static void merge3(int[] nums1,int m,int[] nums2,int n){
        int p1 = m-1,p2 = n-1;
        int temp;
        while (p1>=0 || p2>=0){
            if(p1==-1){
                temp = nums2[p2];
                p2--;
            }else if (p2==-1){
                temp = nums1[p1];
                p1--;
            }else if(nums1[p1]>nums2[p2]){
                temp = nums1[p1];
                p1--;
            }else{
                temp = nums2[p2];
                p2--;
            }

            nums1[p1+p2+2] = temp;
        }
    }

    进阶问题:合并链表并去重,还是利用双指针,只是在nums1[p1]==nums2[p2]条件时,让p1指针直接往后移动即可
    public static int[] merge4(int[] nums1,int m,int[] nums2,int n){
        List<Integer> list = new ArrayList<>();
        int p1 = 0,p2 = 0;
        while(p1<m||p2<n){
            if (p1==m){
                list.add(nums2[p2]);
                p2++;
            }else if(p2==n){
                list.add(nums1[p1]);
                p1++;
            }else if(nums1[p1]==nums2[p2]){
                p1++;
            }else if(nums1[p1]<nums2[p2]){
                list.add(nums1[p1]);
                p1++;
            }else{
                list.add(nums2[p2]);
                p2++;
            }
        }

        int[] ans = new int[list.size()];
        for (int i=0;i<list.size();i++){
            ans[i] = list.get(i);
        }
        return ans;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值