zoukankan      html  css  js  c++  java
  • 【LeetCode刷题记录】21.合并两个有序链表——Java实现

    写这个主要是为了记录自己学习的情况,题有哪些好的解法,用到什么样的知识点,整理一下思绪。
    原文链接https://www.cnblogs.com/HelloXHD/p/12815142.html

    题目

    题目
    题目链接
    这题是简单难度的,两个链表已经是有序状态,思路比较简单。

    题解

    迭代法

    1.设置一个哨兵结点(假结点)pHead,用于作为返回最终结果链表的头指针;
    2.设置一个游标p,随着链表结点的增加移动,初始情况下,p指向pHead;
    3.在l1、l2均未达到链表结尾(null)前提下循环迭代。
    l1当前指向结点的值小于等于l2当前指向结点的值时,p.next指向l1,l1移向下个结点,否则,p.next指向l2,l2移向下个结点;游标p移向下个结点。
    4.由于当循环结束时,l1、l2中有一个仍然非空,所以直接将剩余结点添加。

    初始
    初始状态;
    第一次循环
    第一次循环;
    第二次循环
    第二次循环;(以此类推)
    最后一次循环
    最后一次循环,l1先达到结尾(null);
    结果
    最后将剩余结点全部添加至p.next;

    Java源码:

    class Solution2 {
        public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
            ListNode pHead = new ListNode(-1);//哨兵结点
            ListNode p = pHead;//游标
            while(l1 != null && l2 != null){
                if (l1.val <= l2.val){
                    p.next = l1;
                    l1 = l1.next;
                    p = p.next;
                }else{
                    p.next = l2;
                    l2 = l2.next;
                    p = p.next;
                }
            }
            p.next = l1 == null ? l2 : l1;//添加剩余结点
            return pHead.next;//返回时跳过头结点
        }
    }
    

    算法复杂度:

    时间复杂度:O(N+M),N和M分别为两个有序链表的长度,循环次数不会超过两个长度之和,其他操作的时间复杂度都是常数级别的;
    空间复杂度:O(1),只需要常数的空间存放若干个变量。

    递归法

    这个我没有想到,看了题解后才知道这个解法!
    官方题解中有这样的思路:
    递归法思路

    1.首先,递归终止的条件是l1或l2为空(null);
    2.如果l1.val < l2.val的话,表头就是l1的头结点,否则是l2的头结点;
    3.递归的内容是得到的两个链表中小的结点后,在剩下的结点中找下一个小的结点;





    Java源码:

    class Solution {
        public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
            if (l1 == null){
                return l2;
            }
            else if (l2 == null){
                return l1;
            }
            else if (l1.val < l2.val){
                l1.next = mergeTwoLists(l1.next, l2);
                return l1;
            } else{
                l2.next = mergeTwoLists(l1, l2.next);
                return l2;
            }
        }
    }
    

    算法复杂度:

    时间复杂度:O(n+m),其中 n 和 m 分别为两个链表的长度。因为每次调用递归都会去掉 l1 或者 l2 的头节点(直到至少有一个链表为空),函数 mergeTwoList 至多只会递归调用每个节点一次。因此,时间复杂度取决于合并后的链表长度,即 O(n+m)。
    空间复杂度:O(n+m),递归就是程序内部维护了一个栈,每次将最小值压栈,也就是用一个栈来维护顺序。

    总结

    两种方法虽然时间复杂度一样,但在我实际试验中,递归法效率比迭代法高。

  • 相关阅读:
    博客园培训团队工作进度通报
    ASP.NET 2.0打造购物车和支付系统之二
    vs2005视频教程系列 之 MasterPage创建使用 [视频]
    今天过节,我给自己放假一天,不发布教程!
    Visual Studio 2005入门 之 Table [视频]
    vs2005入门 之 GridView使用基础 [视频]
    存放视频文件的服务器出问题了,所有视频暂时打不开!
    加入博客园培训团队须知
    请关心这个系列教程命运的朋友请进来讨论下!
    未来一周将不能发布教程!
  • 原文地址:https://www.cnblogs.com/HelloXHD/p/12815142.html
Copyright © 2011-2022 走看看