有序链表和数组的合并

一:链表的合并

 思路分析1(双指针解法)

1:定义两个指针遍历l1,l2分别指向第一条链表的头结点list1和第二条链表的头结点list2;

2:定义一个空节点preNode,用于连接两条有序链表,定义一个结果指针指向空节点

3.1:当两条链表的头结点都为空是直接返回null即可

3.2:当两条链表都不为空时,循环比较节点值的大小,将值较小的节点挂载到结果指针之后,并将结果指针后移

3.3:当退出循环时,两条链表有一条为空时,将不为空的链表的所有节点挂载到结果指针之后即可

class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        //定义一个头结点的前驱节点
        ListNode preNode=new ListNode(-1);
        //定义一个指针指向头结点的前驱结点,用于遍历新生成的链表
        ListNode resNode = preNode;
       // 定义一个指针l1指向头结点list1
        ListNode l1=list1;
        // 定义一个指针l2指向头结点list2
        ListNode l2=list2;
        //如果第一个条链表的头结点为空,那么直接返回第二条链表的头结点即可
        if(list1==null){
            return list2;
        }
        如果第二个条链表的头结点为空,那么直接返回第一条链表的头结点即可
        if(list2==null){
            return list1;
        }
        //l1 , l2有一个为空(即有一条链表遍历完毕之后)就退出循环
        while(l1!=null && l2!=null){
            //当第一条链表的头结点小于第二条链表的头结点时
            if(l1.val<l2.val){
                //将l1挂载到头结点的前驱结点之后
                resNode.next=l1;
                //指向第一条链表的指针后移
                l1=l1.next;
            }
            else {
                //否则l2挂载到前驱节点之后
                resNode.next=l2;
                //指针后移
                l2=l2.next;
            }
             //每循环一次,就将将指向前驱节点的指针后移
            resNode=resNode.next;
        }
            //当退出循环时,即两条链表至少有一条为空
            //如果第一条链表遍历完毕,为空时
             if(l1==null){
            //将第二条链表后的所有节点挂载到结果指针上
            resNode.next=l2;
            }
             //如果第二条链表遍历完毕,为空时
             if(l2==null){
            //将第一条链表后的所有节点挂载到结果指针上
            resNode.next=l1;
            }
        return preNode.next;
    }
}

思路分析2(递归解法)

1:先进行头结点是否为空的判断

2:比较两条链表头结点值的大小,如果list1<list2,将list2指向list1,并递归的开始比较list2与第一条链表去除掉list1之后的所有节点

3:如果list2<list1,将list1指向list2,并递归的开始比较list1与第二条链表去除掉list2之后的所有节点

​
class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
     if(list1==null){
         return list2;
     }
     if(list2==null){
         return list1;
     }
     if(list1.val>=list2.val){
         list2.next=mergeTwoLists(list1,list2.next);
         return list2;
     }
     else{
         list1.next=mergeTwoLists(list1.next,list2);
         return list1;
     }
    }
}

​

二:数组的合并

 

思路分析:

1:需要建立一个新数组,大小为m+n;并定义nums1数组的下标变量nums1Index,nums2数组的下标变量nums2Index,新数组的下标变量index

2.1:当nums1数组中的m个元素全部取完时,将nums2数组中的所有元素全部添加到新数组中

2.2:当nums2数组中的n个元素全部取完时,将nums1数组中的所有元素全部添加到新数组中

2.3:如果nums1数组中第nums1Index个元素小于nums2数组中第nums2Index个元素时,将较小的值添加的新数组中,nums1Index后移

2.4:如果nums2数组中第nums2Index个元素小于nums1数组中第nums1Index个元素时,将较小的值添加的新数组中,nums2Index后移

注意:一定要先判断nums1数组和nums2数组是否全部取完,再比较两个数组内元素大小。

如果先判断两个数组内元素大小的话,如nums1 = [1,2,3,0,0,0],就会把3后面的0,0,0输入到新数组中,判断不了nums2数组中剩下的元素

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int k=m+n;
        //定义一个新数组,用于存储排序后的数组元素,数组大小为m+n
        int[] newArr=new int[k];
          int nums1Index=0;
            int nums2Index=0;
        //index指向新数组的第一个元素,下标为0
        for(int index=0;index<k;index++){
             //当nums1数组中所有元素取完时,将nums2数组中的所有元素添加的新数组中
             if(nums1Index >= m){
                newArr[index]=nums2[nums2Index++];
            }
            //当nums2数组中所有元素取完时,将nums1数组中的所有元素添加的新数组中
            else if(nums2Index >= n){
                newArr[index]=nums1[nums1Index++];
            }
            //当nums1数组元素小于nums2数组元素时
            else if(nums1[nums1Index]<nums2[nums2Index]){
                //把较小值添加到新数组中去
                newArr[index]=nums1[nums1Index];
                //并将指针后移
                nums1Index++;
            }
            // 当nums2数组元素小于nums1数组元素时
            else {
                newArr[index]=nums2[nums2Index];
                nums2Index++;
            }
        }
        //题目中要求存储到nums1数组中
        //遍历新数组中的所有元素,取出并存放到nums1中
        for(int i=0;i<k;i++){
            nums1[i]=newArr[i];
        }
    }
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值