• 合并两个有序链表


    今天刷第2道LeetCode题,合并两个有序链表:

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

    示例:

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

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/merge-two-sorted-lists
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    我的解题思路:

      1. 先判断边界条件,如果有任意一个链表为空,则直接返回其中不为空的链表

      2. 然后在一个循环里面,同时从左往右遍历两个链表

      3. 遍历过程中,依次比较两个链表的值,把较小值放入新链表中,然后将对应链表的指针往右移动一位

      4. 重复步骤3,直到:遍历次数超出两个链表长度之和,或者任何一个链表已经遍历到了末尾,则跳出循环

      5. 把未遍历完的链表的后续数值全部放入新链表中,结束

    java实现如下:

        public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    
            //这两个判断可以不需要,因为循环里面已经有条件判断
            /*if (l1 == null) {
                return l2;
            }
            if (l2 == null) {
                return l1;
            }*/
    
            ListNode result = new ListNode();
            //保存头指针,方便输出
            ListNode resultHead = result;
            while (l1 != null && l2 != null) {
                if (l1.val <= l2.val) {
                    //这里可以不new新的节点,可以节省空间;
                    //但是注意,这种做法有个副作用,就是会改变原来的l1,l2的数据,
    //                result.next = l1;
                    //而这种做法,虽然耗费额外的空间,但是对于原来的数据l1和l2不会有影响
                    result.next = new ListNode(l1.val);
                    l1 = l1.next;
                } else {
    //                result.next = l2;
                    result.next = new ListNode(l2.val);
                    l2 = l2.next;
                }
                result = result.next;
            }
    
            //这几行代码可以用3元运算符 ? :替换,更加简洁
            /*if (l1 != null) {
                result.next = l1;
            }
            if (l2 != null) {
                result.next = l2;
            }*/
            result.next = l1 != null ? l1 : l2;
            return resultHead.next;
        }

    官方题解是使用递归来实现的,

    算法
    我们直接将以上递归过程建模,首先考虑边界情况。
    特殊的,如果 l1 或者 l2 一开始就是 null ,那么没有任何操作需要合并,所以我们只需要返回非空链表。否则,我们要判断 l1 和 l2 哪一个的头元素更小,然后递归地决定下一个添加到结果里的值。如果两个链表都是空的,那么过程终止,所以递归过程最终一定会终止。

    作者:LeetCode
    链接:https://leetcode-cn.com/problems/merge-two-sorted-lists/solution/he-bing-liang-ge-you-xu-lian-biao-by-leetcode/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    /**
         * 官方题解
         * 算法
         * 我们直接将以上递归过程建模,首先考虑边界情况。
         * 特殊的,如果 l1 或者 l2 一开始就是 null ,那么没有任何操作需要合并,所以我们只需要返回非空链表。否则,我们要判断 l1 和 l2 哪一个的头元素更小,然后递归地决定下一个添加到结果里的值。如果两个链表都是空的,那么过程终止,所以递归过程最终一定会终止。
         * <p>
         * 注意,该方法会修改l1和l2的数据,l1变成了: 1->2->3->4->4,l2变成了:1->1->2->3->4->4,并且l2的第2个节点开始是引用的l1的数据,也就是两者是共享部分内存数据的。
         * 而这种数据结构,如果被类似递归的方法重新调用的话,可能产生两个链表互相引用的情况,形成引用环,那在遍历两个链表时,就会陷入死循环,最后可能会导致内存耗尽系统崩溃。
         *
         * @param l1
         * @param l2
         * @return practice.zxz.leetcode.two_sum.ListNode
         * @author Zxz
         * @date 2019/10/12 10:44
         **/
        public static ListNode mergeTwoLists2(ListNode l1, ListNode l2) {
            if (l1 == null) {
                return l2;
            } else if (l2 == null) {
                return l1;
            } else if (l1.val < l2.val) {
                l1.next = mergeTwoLists2(l1.next, l2);
                return l1;
            } else {
                l2.next = mergeTwoLists2(l1, l2.next);
                return l2;
            }
    
        }
    
        /**
         作者:LeetCode
         链接:https://leetcode-cn.com/problems/merge-two-sorted-lists/solution/he-bing-liang-ge-you-xu-lian-biao-by-leetcode/
         来源:力扣(LeetCode)
         著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
         */

    递归算法实现起来,果然代码可读性更好一些。

    但是递归算法会修改原有链表的数据,这是该算法的一个副作用,使用的时候要注意,否则可能导致问题(比如,再次该递归方法,那么最终的链表数据会导致循环引用,遍历时就会陷入死循环)

  • 相关阅读:
    Python之二维数组(list与numpy.array)
    too many values to unpack
    python 寻找可迭代(list)的目标元素的下表方法
    zip函数
    map函数
    Sokcet代码错误类型
    PL-VIO Docker测试
    如何检索国外博士论文
    EuRoc V203数据集的坑
    Tracking of Features and Edges
  • 原文地址:https://www.cnblogs.com/zhangxuezhi/p/11656732.html
Copyright © 2020-2023  润新知