21. 合并两个有序链表

迭代

class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {

        /**
         * 依次比较两个链表的节点,将较小的节点放入新的链表
         */
        ListNode dummyHead = new ListNode();
        ListNode cur = dummyHead;
        
        while (list1 != null && list2 != null){

            if (list1.val <= list2.val){

                cur.next = list1;
                cur = cur.next;
                list1 = list1.next;
            }
            else {

                cur.next = list2;
                cur = cur.next;
                list2 = list2.next;
            }
        }

        /**
         * 直接指向那个非空的链表
         */
        cur.next = list1 == null ? list2 : list1;

        return dummyHead.next;
    }
}

/**
 * 时间复杂度 O(n)
 * 空间复杂度 O(1)
 */

递归复杂版

public class Algorithm {

    public static void main(String[] args) {

        int[] arr1 = {1, 2, 4};
        int[] arr2 = {1, 3, 4};
        ListNode head1 = new ListNode(arr1);
        ListNode head2 = new ListNode(arr2);

        System.out.println(head1);
        System.out.println(head2);

        System.out.println(new Solution().mergeTwoLists(head1, head2));
    }
}

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {

        if (l1 == null){
            return l2;
        }

        if (l2 == null){
            return l1;
        }

        if (l1 == null && l2 == null){
            return null;
        }

        /**
         * 将l1链表插入l2中,假设除了头节点l1,剩下的子链表都已经插入完成
         * 此时再将l1插入新的small链表
         */
        ListNode small = mergeTwoLists(l1.next, l2);

        ListNode curr = small;

        /**
         * 当新链表的节点数目大于1时,将l1和small链表中的元素进行比较
         */
        while (curr.next != null){

            /**
             * 情况一:l1是最小的
             */
            if (small.val >= l1.val){

                l1.next = curr;
                return l1;
            }

            /**
             * 情况二:l1插入small中间
             */
            if (curr.val < l1.val && curr.next.val >= l1.val) {

                ListNode next = curr.next;
                curr.next = l1;
                l1.next = next;
                return small;
            }

            curr = curr.next;
        }

        /**
         * 如果small节点数目为1,上面的while循环不会执行
         * 此处要额外判断一下,有可能small是最大的
         */
        if (small.val > l1.val){

            l1.next = small;
            return l1;
        }
        
        /**
         * 情况三:l1是最大的
         */
        curr.next = l1;
        l1.next = null;

        return small;
    }
}

class ListNode{

    int val;
    ListNode next;
    ListNode() {}

    ListNode(int val) {

        this.val = val;

    }

    ListNode(int val, ListNode next) {

        this.val = val; this.next = next;
    }

    ListNode(int[] arr){

        if (arr == null || arr.length == 0){
            throw new IllegalArgumentException("数组是空的");
        }

        this.val = arr[0];
        ListNode prev = this;

        for (int i = 1; i < arr.length; i++) {

            prev.next = new ListNode(arr[i]);
            prev = prev.next;
        }
    }

    @Override
    public String toString(){

        StringBuilder str = new StringBuilder();

        ListNode curr = this;
        while (curr != null){
            str.append(curr.val + "——>");
            curr = curr.next;
        }
        str.append("null");

        return str.toString();
    }
}

/**
 * 时间复杂度 O(n)
 * 空间复杂度 O(n)
 */

递归简化版

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {

        /**
         * 边界条件
         * 如果有一个链表为空,就直接返回另一个
         */
        if (l1 == null){
            return l2;
        }

        if (l2 == null){
            return l1;
        }

        /**
         * 假设除了最小的那个节点,其他的节点都已经插入完毕
         * 只需要比较出最小的那个头节点,直接指向递归的结果
         * 递归需要调用栈空间,取决于递归的深度,此处即链表的长度
         */
        if (l1.val <= l2.val){

            l1.next = mergeTwoLists(l1.next, l2);
            return l1;
        }
        else {

            l2.next = mergeTwoLists(l2.next, l1);
            return l2;
        }
    }
}

/**
 * 时间复杂度 O(n)
 * 空间复杂度 O(n)
 */

https://leetcode-cn.com/problems/merge-two-sorted-lists/

posted @ 2021-10-18 15:17  振袖秋枫问红叶  阅读(39)  评论(0)    收藏  举报