• 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;
        }

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

  • 相关阅读:
    宏定义抽取单例
    谓词基本使用
    Xcode静态分析工具--Analyze
    [转载]CocoaPods管理第三方开源框架
    @import--iOS7新关键字
    iOS手势识别
    UINavigationController
    JSON解析--原生&AFN
    UITabBarController
    iOS APP EuclidStudy Service Support
  • 原文地址:https://www.cnblogs.com/bufferflies/p/7644347.html
Copyright © 2020-2023  润新知