LeetCode刷题之合并两个有序链表

2024/5/10 今天能见度很高,学校南面是山,北校区建立于湖中,北面是湖公园。放几张近期我拍的照片:

在这里插入图片描述

和室友上周周末去学校对面公园散步所拍,正好有人在拍结婚照

在这里插入图片描述

一天吃完晚饭回实验室所拍,楼即实验室

在这里插入图片描述

五一假期去长乐所拍,那天第一次见到有沙滩的大海,下大雨,沿着沙滩一直走,浪漫至极,一瞬我在想我要死也要死在海边的沙滩边,捡了许多贝壳,还有搁浅的船

在这里插入图片描述

湖对岸的天主教堂,福建这边宗教很多,文化颇富,甚喜。

今天下午一点开组会,开到了五点,吃饭、散步、回实验室。看了两集仙剑奇侠传三,听着阿桑的《一直很安静》,敲一行行的字,做题。

1、题目描述

在这里插入图片描述

2、逻辑分析

这种类型的题,我考研那段时间做过。大致思路是:令给定的两个链表。一个为A,另一个自然就令其为B,接着建立一个C的空链表。分别用索引从A、B链表中依次取元素,小的排前面,大的排后面。有一种情况就是A和B的长度不相等,那么那个长的链表在另一链表元素全部写进C链表后,再将剩余元素写进去,最后返回C链表即可,当时用的伪代码,所以现在的我不会动手,决计看看题解。

题解表示不允许再建立一个链表,只能在存在的链表上操作,有两种方式,第一种是迭代,另一种是递归,我喜欢抽象的事物,更偏向于递归,先看迭代吧,代码如下:

3、代码演示

public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode prehead = new ListNode(-1);
        ListNode prev = prehead;
        while(list1 != null && list2 != null){
            if(list1.val <= list2.val){
                prev.next = list1;
                list1 = list1.next;
            }else{
                prev.next = list2;
                list2 = list2.next;
            }
            prev = prev.next;
        }
        prev.next = list1 == null ? list2:list1;
        return prehead.next; 
}

在这里插入图片描述

(1)其中,使用了一个虚拟头节点 prehead 来简化操作。这个虚拟头节点本身并不包含任何有意义的数据,它仅仅是一个哨兵节点(或称为哑节点、占位节点),用来帮助我们在合并链表时不需要考虑空指针的情况。

(2)在合并过程中,我们维护了一个指针 prev,它始终指向当前已合并部分的最后一个节点。当 list1 和 list2 两个链表中的节点都被遍历完时,prev 将指向合并后链表的最后一个节点。

(3)由于我们使用了 prehead 这个虚拟头节点,因此合并后链表的真正头节点并不是 prev 所指向的节点,而是 prev 的下一个节点,即 prehead.next。这是因为 prev 在循环中始终会向后移动,直到它指向最后一个被合并的节点,而 prehead.next 才是合并后链表的第一个节点。在合并结束后,我们需要返回prehead.next

时间复杂度:O(m+n),空火箭复杂度:O(1)。

大致逻辑就是以上了,好了,我们来看递归实现。

直接上代码:

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

理解递归就是要理解递归。递归给人的感觉就是一层层揭开神秘面纱,探求幽幽深处。

使用递归需要两点:第一点即我要用递归来做什么;第二点即递归的结束条件是什么。本题中,我们的目的就是将两个有序链表合并成一个有序链表。条件是:我们递归地合并 list1 的剩余部分(即 list1.next)和 list2 的整个链表,并将合并后的结果设置为 list1 的下一个节点。然后返回 list1 作为合并后链表的头节点;list2同理。通过这种方式,我们不断地递归地将两个链表拆分成更小的部分,直到一个链表为空,然后我们将非空链表与空链表(或另一个已排序的链表部分)合并。最终,我们得到一个合并后的已排序链表。

时间复杂度:O(m+n);空间复杂度:O(m+n)。

说实话,这个题我感觉有点难,引入了链表的指针概念,还有抽象的递归。但是我会坚持下去滴,好累呀,眼睛看的好痛,我去看会电视再学学java项目,GOOD NIGHT!

相关推荐

  1. Leetcode合并有序

    2024-05-11 08:44:02       6 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-11 08:44:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-11 08:44:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-11 08:44:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-11 08:44:02       18 阅读

热门阅读

  1. 力扣每日一题40:组和总数||

    2024-05-11 08:44:02       9 阅读
  2. 医院预约挂号系统微信小程序APP

    2024-05-11 08:44:02       8 阅读
  3. SpringBoot整合定时任务

    2024-05-11 08:44:02       12 阅读
  4. 共享旅游革命:千益畅行卡的优势揭秘

    2024-05-11 08:44:02       9 阅读
  5. 蓝桥杯 算法提高 ADV-1164 和谐宿舍 python AC

    2024-05-11 08:44:02       9 阅读
  6. 集团公司非结构化数据平台建设方案

    2024-05-11 08:44:02       8 阅读
  7. ubuntu postgresql 安装

    2024-05-11 08:44:02       9 阅读