zoukankan      html  css  js  c++  java
  • LeetCode#21-Merge Two Sorted Lists-合并两个有序链表

    一、题目

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

    示例:

    输入:1->2->4, 1->3->4
    输出:1->1->2->3->4->4
    

    二、题解

    • 解法1:递归

    终止条件:两条链表分别为 l1 和 l2,当 l1 为空或 l2 为空时结束。
    如何递归:判断 l1 和 l2 头结点哪个更小,然后较小结点的 next 指针指向其余结点的合并结果。(调用递归)

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

    <?php
    
    class ListNode {
        public $val = 0;
        public $next = null;
        function __construct($val) { 
            $this->val = $val; 
        }
    }
    
    /**
     * @param ListNode $l1
     * @param ListNode $l2
     * @return ListNode
     */
    function mergeTwoLists($l1, $l2) {
        if ($l1 == null) {
            return $l2;
        }
        if ($l2 == null) {
            return $l1;
        }
    
        if ($l1->val <= $l2->val) {
            $l1->next = mergeTwoLists($l1->next, $l2);
            return $l1;
        }
        if ($l2->val <= $l1->val) {
            $l2->next = mergeTwoLists($l2->next, $l1);
            return $l2;
        }
    }
    
    /**
     * 构建一个单链表(将数组转换成链表)
     */
    function createLinkedList($arr)
    {
        $linkedList = [];
        $current = new ListNode(array_shift($arr)); //头节点
        while (!empty($arr)) {
            while ($current->next != null) {
                $linkedList[] = $current;
                $current = $current->next;
            }
            $current->next = new ListNode(array_shift($arr));
        }
    
        return $linkedList[0];
    }
    
    $l1 = createLinkedList([1,2,4]);
    $l2 = createLinkedList([1,3,5]);
    
    $res = mergeTwoLists($l1, $l2);
    print_r($res);
    

    得到的结果如下:

    ListNode Object
    (
        [val] => 1
        [next] => ListNode Object
            (
                [val] => 1
                [next] => ListNode Object
                    (
                        [val] => 2
                        [next] => ListNode Object
                            (
                                [val] => 3
                                [next] => ListNode Object
                                    (
                                        [val] => 4
                                        [next] => ListNode Object
                                            (
                                                [val] => 5
                                                [next] => 
                                            )
                                    )
                            )
                    )
            )
    )
    
    • 解法2:迭代

    设定一个哨兵节点,用来返回合并后的链表,维护一个 pre 节点,调整它的 next 指针。

    当 l1 当前位置的值小于等于 l2,就将 pre 节点的 next 指向 l1 的这个值,同时将 l1 指针往后移一个。反之则对 l2 做同样的操作,直到 l1 或者 l2 指向 null。当循环终止的时候,l1 和 l2 至多有一个是非空的。

    由于输入的两个链表都是有序的,所以不管哪个链表是非空的,只需要将剩下的那个非空链表接在合并链表的后面,并返回合并链表即可。

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

    /**
     * @param ListNode $l1
     * @param ListNode $l2
     * @return ListNode
     */
    function mergeTwoLists($l1, $l2) {
        // 设置一个哨兵
        $node = new ListNode(null);
        $pre = $node;
        while ($l1 != null && $l2 != null) {
            if ($l1->val < $l2->val) {
                $pre->next = $l1;
                $l1 = $l1->next;
            } else {
                $pre->next = $l2;
                $l2 = $l2->next;
            }
            $pre = $pre->next;
        }
        if ($l1 == null) {
            $pre->next = $l2;
        } 
        if ($l2 == null) {
            $pre->next = $l1;
        }
        
        return $node->next;
    }
    
  • 相关阅读:
    split函数的修改,通过存储过程实现整表所有列的拆分
    在本机上安装zabbix,来监控服务器 三
    我第一篇博客
    渗透测试常用工具-网络嗅探
    渗透测试常用工具-Metasploit
    渗透测试常用工具-ADMsnmp进行snmp分析
    渗透测试常用工具-amap服务枚举
    渗透测试常用工具-端口扫描
    渗透测试常用工具-目标识别
    Meterpreter(后渗透命令)笔记
  • 原文地址:https://www.cnblogs.com/sunshineliulu/p/12657482.html
Copyright © 2011-2022 走看看