leetCode第21题——合并两个有序链表

Posted 小志的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetCode第21题——合并两个有序链表相关的知识,希望对你有一定的参考价值。

一、题目

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
提示:两个链表的节点数目范围是 [0, 50]

示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例 2:
输入:l1 = [], l2 = []
输出:[]

示例 3:
输入:l1 = [], l2 = [0]
输出:[0]

二、迭代方式实现的思路

  • 当 l1 和 l2 都不是空链表时,判断 l1 和 l2 哪一个链表的头节点的值更小,将较小值的节点添加到结果里,当一个节点被添加到结果里之后,将对应链表中的节点向后移一位。

三、题目代码解析(迭代方式实现)

1、创建一个链表类

public class ListNode {
    public int val;//值
    public ListNode next;//指向下一个节点

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

    public int getVal() {
        return val;
    }

    public void setVal(int val) {
        this.val = val;
    }

    public ListNode getNext() {
        return next;
    }

    public void setNext(ListNode next) {
        this.next = next;
    }

    @Override
    public String toString() {
        return "ListNode{" +
                "val=" + val +
                '}';
    }
}

2、题解代码

public class Test {
    public static void main(String[] args) {
        //创建l1链表
        ListNode l1=new ListNode(1);
        ListNode node2=new ListNode(2);
        ListNode node3=new ListNode(4);
        l1.next=node2;
        node2.next=node3;

        //创建l2链表
        ListNode l2=new ListNode(1);
        ListNode node4=new ListNode(3);
        ListNode node5=new ListNode(4);
        l2.next=node4;
        node4.next=node5;

        //迭代方式合并两个有序链表
        ListNode listNode=mergeTwoList(l1,l2);

        //遍历输出链表节点
        while (listNode != null) {
            System.out.println(listNode.getVal());
            listNode = listNode.getNext();
        }
    }
    
    /**
     * 迭代方式实现
     */
    public static ListNode mergeTwoList(ListNode l1, ListNode l2) {
        ListNode prehead = new ListNode(-1);
        ListNode prev = prehead;//维护一个 prev 指针,即头指针
        while (l1 != null && l2 != null) {//l1或者l2都不为null
            if (l1.val <= l2.val) {//l1当前节点的值小于等于l2
                prev.next = l1;//把l1当前的节点接在 prev 节点的后面
                l1 = l1.next;//同时将l1指针往后移一位
            } else {//则否
                prev.next = l2;//把l2当前的节点接在 prev 节点的后面
                l2 = l2.next;//同时将l2指针往后移一位
            }
            //不管我们将哪一个元素接在了后面,我们都需要把 prev 向后移一位。
            prev = prev.next;
        }

        // 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
        prev.next = l1 == null ? l2 : l1;

        return prehead.next;
    }
}

3、结果如下图:

四、递归实现的思路

  • 如果 l1 或者 l2 一开始就是空链表 ,那么没有任何操作需要合并,所以我们只需要返回非空链表。
  • 否则,我们要判断 l1 和 l2 哪一个链表的头节点的值更小,然后递归地决定下一个添加到结果里的节点。如果两个链表有一个为空,递归结束。

五、题目代码解析(递归方式实现)

1、创建一个链表类

public class ListNode {
    public int val;//值
    public ListNode next;//指向下一个节点

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

    public int getVal() {
        return val;
    }

    public void setVal(int val) {
        this.val = val;
    }

    public ListNode getNext() {
        return next;
    }

    public void setNext(ListNode next) {
        this.next = next;
    }

    @Override
    public String toString() {
        return "ListNode{" +
                "val=" + val +
                '}';
    }
}

2、题解代码

public class Test {
    public static void main(String[] args) {
        //创建l1链表
        ListNode l1=new ListNode(1);
        ListNode node2=new ListNode(2);
        ListNode node3=new ListNode(4);
        l1.next=node2;
        node2.next=node3;

        //创建l2链表
        ListNode l2=new ListNode(1);
        ListNode node4=new ListNode(3);
        ListNode node5=new ListNode(4);
        l2.next=node4;
        node4.next=node5;

        //递归方式合并两个有序链表
        ListNode listNode=mergeTwoLists(l1,l2);

        //遍历输出链表节点
        while (listNode != null) {
            System.out.println(listNode.getVal());
            listNode = listNode.getNext();
        }
    }
     /**
     *  递归实现
     */
    public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode  listNode;//声明一个空的链表
        if (l1 == null) {//如果 l1一开始就是空链表,那么没有任何操作需要合并,所以我们只需要返回非空链表。
            return l2;
        } else if (l2 == null) {//如果 l2一开始就是空链表,那么没有任何操作需要合并,所以我们只需要返回非空链表。
            return l1;
        } else if (l1.val < l2.val) {//如果l1链表的头节点的值 小于 l2链表的头节点的值
            l1.next = mergeTwoLists(l1.next, l2);//递归地决定下一个添加到结果里的节点。如果两个链表有一个为空,递归结束。
            listNode=l1;
            return listNode;
        } else {//如果l1链表的头节点的值 大于 l2链表的头节点的值
            l2.next = mergeTwoLists(l1, l2.next);//递归地决定下一个添加到结果里的节点。如果两个链表有一个为空,递归结束。
            listNode=l2;
            return listNode;
        }
    }
}

3、结果如下图:

以上是关于leetCode第21题——合并两个有序链表的主要内容,如果未能解决你的问题,请参考以下文章

精选力扣500题 第7题 LeetCode 21. 合并两个有序链表c++详细题解

Leetcode第21题:合并两个有序链表

Leetcode第21题:合并两个有序链表

Leetcode练习(Python):链表类:第21题:合并两个有序链表:将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

LeetCode Algorithm 21. 合并两个有序链表

LeetCode Algorithm 21. 合并两个有序链表