合并两个有序链表——LeetCode

一、链表节点

    public static class ListNode {
        public int val;
        public ListNode next;

        public ListNode(int val) {
            this.val = val;
        }
    }

二、循环解法

思想和归并排序有点像,注意指针操作。

    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode header = null; //header作为合并后的新链表的头节点
        ListNode temp = null; //temp用来做新链表的操作指针,来链接新的节点

        while (list1 != null && list2 != null) {
            if (list1.val < list2.val) { //比较两个链表当前节点的大小,选择更小的插入新的链表末尾
                if (header == null) { // 如果新链表是空的,就作为新链表的头节点
                    temp = list1;
                    header = temp;
                } else { //如果新链表不为null,就链接到新链表的末尾,末尾指针用temp来维护
                    temp.next = list1;
                    temp = temp.next;
                }
                list1 = list1.next; //把更小的那个节点链接到新链表上之后,需要维护一下旧链表的指针让它移动到下一个待比较的节点
                //我们没有创建新的节点去构造新的链表,而是直接修改旧链表的指针,这样会不会对旧链表产生影响,比如丢失指针,指针错乱等问题?
                //经过分析发现,可能造成指针错乱等问题的是 temp.next = list 这句,因为它修改了旧链表next指针,仔细思考就会发现
                //它动的不是当前元素的next,而是上一个元素的next,并不会影响当前元素查找下个元素
                //顺带说一下指针,比如有A和B,同时指向List1这个节点,如果仅仅改变A的指向,比如A改为指向List2,这并不会影响B和List1
                //如果改变A.next那B和List1的next也会改变,总结成书面语言叫啥来着我给忘了,如果长时间不接触指针突然想到这个点还真让我别扭了一下
            } else {
                if (header == null) {
                    temp = list2;
                    header = temp;
                } else {
                    temp.next = list2;
                    temp = temp.next;
                }
                list2 = list2.next;
            }
        }

        if (list1 == null) { //如果其中一个链表遍历完了,把另一个链表剩下的节点直接放到新链表的后面,要注意开始其中一个链表为null的情况
            if (header == null) {
                header = list2;
            } else {
                temp.next = list2;
            }
        } else {
            if (header == null) {
                header = list1;
            } else {
                temp.next = list1;
            }
        }

        return header;
    }

三、递归解法

    public static ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        if (list1 == null) return list2;
        if (list2 == null) return list1;

        ListNode headerAndTemp = null; //第一次调用,存储的是新链表头节点
        if (list1.val < list2.val) {
            headerAndTemp = list1;
            headerAndTemp.next = mergeTwoLists(list1.next,list2); //每次都是返回更小的那个,然后通过headerAndTemp.next来维护新链表
        }else {
            headerAndTemp = list2;
            headerAndTemp.next = mergeTwoLists(list1,list2.next);
        }

        return  headerAndTemp; // 最后一次返回的是,第一次调用,即返回的是第一次存储的头节点
    }

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值