0
点赞
收藏
分享

微信扫一扫

leetcode 21、合并两个有序链表 mergeTwoLists

肉肉七七 2022-02-09 阅读 32

题目

题目给出的升序链表类:

    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; }
    }

题解

题目给出的链表类中,有两个属性,int val 以及 ListNode next,还有三个构造方法。val是一个int类型,是一个数值,而next是ListNode类的对象,即自身的一个对象。

所以不难看出,val代表的是当前节点的数值,next代表的是下一个节点,因为next对象中也有val和next属性,所以也可以填充数值以及扩充下一个节点。这样就可以使用这样的一个类,来代表一个链表了。

1、递归

    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        if (list1 == null) {
            return list2;
        } else if (list2 == null) {
            return list1;
        } else if (list1.val < list2.val) {
            list1.next = mergeTwoLists(list1.next, list2);
            return list1;
        } else {
            list2.next = mergeTwoLists(list1, list2.next);
            return list2;
        }
    }

所谓“递归”,我的理解就是自身调自身。相当于另一种循环,只不过循环体是整个方法。

代码中 第一二种分支很好理解:假如list1为空,那么直接返回list2,假如list2为空,那么直接返回list1。例如 list1=[1,2,3],list2=[],那么直接返回list1就可以了。

第三种分支我个人的理解如下:
1、当list1的节点值小于list2的节点值时,例如list1的第一个节点为1,list2的第一个节点为2。这时应该先把list1[0]放到第一位,接下来需要比较list1的下一个节点(list1.next)与list2的第一个节点的值,所以就拿list1.next(list1的第二个节点)和list2作为参数再次调自身这个方法。返回的值应该是数值小的那个节点,即如果list1.next 的数值较小,就返回list1.next,反之亦然。

2、这样就可以在比较的过程中,将两个链表的节点按照大小顺序连接起来,赋值给list1.next,而list1[0]即为最小的节点。那么list1(list1[0]+list1.next)就是排序完毕后的最终链表,将其返回。

第四种分支同理

2、迭代

        public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        //哨兵节点
        ListNode node0 = new ListNode(0);
        //指针
        ListNode pointer = node0;
        //链表1和链表2均不为null的情况下 循环
        while (list1 != null && list2 != null) {
            //list1的节点小于list2的节点时
            if (list1.val < list2.val) {
                //将数值小的节点拼接到哨兵节点后面,连接成链表
                pointer.next = list1;
                //将指针移动到下一个节点
                pointer = pointer.next;
                //将list1的下一个节点的值赋给list1,方便循环。跟i++类似
                list1 = list1.next;
            } else {
                //list1的节点大于list2的节点、或两节点值相等时,都可以走这个分支处理
                //将数值小的节点拼接到哨兵节点后面,连接成链表
                pointer.next = list2;
                //将指针移动到下一个节点
                pointer = pointer.next;
                //将list2的下一个节点的值赋给list2,方便循环。跟i++类似
                list2 = list2.next;
            }
        }
        //当其中一个链表为空后,指针后面剩下的部分,直接连接上另一个链表即可
        pointer.next = null == list1 ? list2 : list1;
        //node0[0]为设置的哨兵节点,list1和list2中是不包含这个节点的,所以返回node0.next
        return node0.next;
    }

这种解法就是比较list1和list2的每一个节点,小的就排在前面,然后指针后移,继续比较下一个节点。注释中已经写的很详细了。

举报

相关推荐

0 条评论