zoukankan      html  css  js  c++  java
  • 图解算法——合并两个有序链表

    1. 题目描述

    将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode() {}
     *     ListNode(int val) { this.val = val; }
     *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     * }
     */
    class Solution {
        public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    
        }
    }
    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/merge-two-sorted-lists/
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    2.示例

    示例 1:

    输入:l1 = [1,2,4], l2 = [1,3,4]
    输出:[1,1,2,3,4,4]

    示例 2:

    输入:l1 = [], l2 = []
    输出:[]

    示例 3:

    输入:l1 = [], l2 = [0]
    输出:[0]

    3. 题目要求:

    • 两个链表的节点数目范围是 [0, 50]
    • -100 <= Node.val <= 100
    • l1 和 l2 均按 非递减顺序 排列

    4. 题目解析

    由示例2我们知道,当两个链表都为空时,返回空;当有一个为空时,直接返回另一个非空链表。这两个示例告诉了我们的临界情况。

    一般情况就是示例1所示。

    我们可以设置一个返回节点值ListNode res, 和一个当前节点值curNode;然后令res = curNode,在整个过程中,我们只使用curNode,res是作为返回值使用,因为要保持一个指向链表节点的节点指针。

    思路是:先随意new一个值,使得curNode不为空。然后从 l1 链表和 l2 链表中头部开始,各挑出一个节点,比较大小,谁小,就让curNode的next指向谁,然后小的链表的指针指向该小节点的next位置,最后更新curNode节点使其指向curNode.next。进行下一次比较,直至 l1 和 l2 有不为空的情况。

    当跳出循环时,说明 l1 和 l2 肯定至少有一个为空。谁为空,那就让curNode.next直接指向另一个非空的节点。

    最后返回我们的返回节点res.next。有人会问不应该是res 嘛?怎么变成res.next 了?

    仔细回想一下,我们一开始为了不让curNode 不为空,我们随机设置了一个值。而该值是没有意义的,真正来自l1 和 l2 的值是从 res.next 才开始的。

    代码如下:

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode() {}
     *     ListNode(int val) { this.val = val; }
     *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     * }
     */
    class Solution {
        public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
         //临界判断
            if(l1==null && l2==null){
                return null;
            }
            if(l1 == null){
                return l2;
            }
            if(l2 == null){
                return l1;
            }
            
            ListNode curNode = new ListNode(-1);
            ListNode res = curNode;
            while(l1!=null && l2!=null){
                if(l1.val <= l2.val){
                    curNode.next = l1;
                    l1 = l1.next;
                }else{
                    curNode.next = l2;
                    l2 = l2.next;
                }
                curNode = curNode.next;
            }
            if(l1==null){
                curNode.next = l2;
            }
            if(l2==null){
                curNode.next = l1;
            }
            return res.next;
        }
    }

    5、附录

    在这里我提交了两次,很幸运都直接通过了,哈哈哈。

    第一次就直接获得了如下战绩,但是我想把开头的临界判断给去掉试试效果,没想到执行用时也没增加多少,但是从击败人数上看,明显的是思路不太完整。所以,不要小看这些临界条件,有时候会帮你省很多时间。

    下图:加上临界判断:

     下图:去掉临界判断:

    Over...............

  • 相关阅读:
    /etc/sysctl.conf 控制内核相关配置文件
    python 并发编程 非阻塞IO模型
    python 并发编程 多路复用IO模型
    python 并发编程 异步IO模型
    python 并发编程 阻塞IO模型
    python 并发编程 基于gevent模块 协程池 实现并发的套接字通信
    python 并发编程 基于gevent模块实现并发的套接字通信
    python 并发编程 io模型 目录
    python 并发编程 socket 服务端 客户端 阻塞io行为
    python 并发编程 IO模型介绍
  • 原文地址:https://www.cnblogs.com/gjmhome/p/15004606.html
Copyright © 2011-2022 走看看