21. Merge Two Sorted Lists

题目来自于leetcode,要求是将两个已经有序的链表拼接成一个有序的链表,链表结构如下:

public class ListNode{
        int val;
        ListNode next;
        ListNode(int x){
            val=x;
        }
    }

示意图如下,一个长方形成为节点,一个链表至少有一个节点。

方法一:首先创建一个新的链表L,比较了L1L2当前结点的Val,小的加入到L中,同时将节点向后移,

    直到有一个链表为空。最后将另一个非空的链表添加到L即可。时间复杂度为O(n+m).

    Header:新链表的头节点,pre作为当前链表的最后一个节点,具体步骤如下:

    1.判断L1和L2其中一个是否为空,若有为空,执行3,否则执行2

    2.比较L1和L2的Val值,小的添加到pre节点的后面,并向右移动一个节点(ListNode=ListNode.next,注意此时链表ListNode已经发生改变了),

    同时pre指向Header链表的最后一个。执行1.

    3.若L1不为空,则将L1添加到pre的后面。若L2不为空则将L2添加到pre节点的后面。

    具体实现代码如下:

public ListNode mergeTwoLists(ListNode l1, ListNode l2){

        ListNode header=new ListNode(0);
        ListNode pre=header;
        while(l1!=null&&l2!=null){
            if(l1.val>l2.val){
                pre.next=l2;
                l2=l2.next;
            }else{
               pre.next=l1;
               l1=l1.next;
            }
            pre=pre.next;
        }
        if(l2!=null){
            pre.next=l2;
        }
        if(l1!=null){
            pre.next=l1;
        }
        return header.next;
    }

方法二:由于L1和L2已经是有序了,所以可以考虑将L2插入到L1中,这里只讲插入操作怎么进行,具体过程看java代码

    

    Header 任然为头结点,pre为当前节点的末节点,,红线代表需要修改的指向,绿线代表需要删除的指向

,现在考虑L2的Val比L1小的情况,

    插入步骤如下:

    1。保留L2下一个节点为next

    2.修改L2下一个节点的指向为pre指向的下个节点

    3.修改pre指向的节点为L2

    4.将pre和L2各自向右移动一个节点

    具体代码如下:

public ListNode mergeTwoLists(ListNode l1, ListNode l2){
        ListNode helper=new ListNode(0);
        ListNode pre=helper;
        helper.next=l1;
        while(l1!=null&&l2!=null){
            if(l1.val>l2.val){
                ListNode next=l2.next;
                l2.next=pre.next;
                pre.next=l2;
                l2=next;
            }else{
                l1=l1.next;
            }
            pre=pre.next;
        }
        if(l2!=null){
            pre.next=l2;
        }
        return helper.next;
    }

 方法3:采用递归的思想,若将函数看成求两个链表当前较小的节点,递归结束为两个链表中有一个为null。

    步骤一:1.创建一个节点header为L1和L2较小的节点

        2.创建一个中间变量nonheader为L1和L2较大的节点

·         3.将header下个节点指向递归函数的返回结果,但此时传参中header已经向右移动了一个单位

   

  代码如下:

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1==null) return l1;
        if(l2==null) return  l2;
        ListNode head=(l1.val<l2.val)?l1:l2;
        ListNode nonhead=(l1.val<l2.val)?l2:l1;
        head.next=mergeTwoLists(head.next,nonhead);
        return  head;
    }

这三种方法都可以实现,总体效果最好的时递归的方法。如有纰漏,希望能得到大家的帮助。

原文地址:https://www.cnblogs.com/bufferflies/p/7644347.html