LeetCode算法 -- 合并两个有序链表(第7题)

一、递归算法介绍

什么是递归呢?
函数在运行时调用自己,这个函数就叫做递归函数,调用的过程叫做递归。比如定义一个函数 f(x) = x + f(x-1):

public int add(int num) {
     
	return num + add(num - 1);
}

如果传入参数 f(2):
返回 2 + f(1);
调用 f(1);
返回 1 + f(0);

这时候程序就会一直运行下去,直到内存溢出,程序崩溃。

如果现在加一个判断条件 x > 0:

public int add(int num) {
     
	if (num > 0) {
     
		return num + add(num - 1);
	}else {
     
		return 0;
	}
}

现在计算 f(2) = 2 + f(1) = 2 + 1 + f(0) = 2 + 1 + 0 = 3。

总结:
1、递归函数必须要有一个出口,也就是中止条件,否则会无限递归下去。
2、递归函数先不断调用自身,直到遇到终止条件后进行回溯,最终返回答案。

二、用递归方法解决问题

2.1 题目描述

LeetCode算法 -- 合并两个有序链表(第7题)_第1张图片

2.2 求解方法

根据以上规律考虑本题目:

  • 终止条件:当两个链表都为空时,表示我们对链表已合并完成。
  • 如何递归:我们判断 l1 和 l2 头结点哪个更小,然后较小结点的 next 指针指向其余结点的合并结果。

LeetCode算法 -- 合并两个有序链表(第7题)_第2张图片
LeetCode算法 -- 合并两个有序链表(第7题)_第3张图片
LeetCode算法 -- 合并两个有序链表(第7题)_第4张图片
LeetCode算法 -- 合并两个有序链表(第7题)_第5张图片
LeetCode算法 -- 合并两个有序链表(第7题)_第6张图片
LeetCode算法 -- 合并两个有序链表(第7题)_第7张图片
LeetCode算法 -- 合并两个有序链表(第7题)_第8张图片
LeetCode算法 -- 合并两个有序链表(第7题)_第9张图片

2.3 编写代码

1、编写 ListNode 类

package question7;

/**
 * @description: 定义一个链表节点
 * @author: hyr
 * @time: 2020/3/28 19:18
 */
public class ListNode {
     
    int val;
    ListNode next;

    public ListNode(int x){
     
        val = x;
    }

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

2、编写 Solution 类

package question7;

/**
 * @description: 将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
 * @author: hyr
 * @time: 2020/3/28 19:20
 */
public class Solution {
     
    public static void main(String[] args) {
     
        // 第一个链表
        ListNode node1 = new ListNode(1);
        ListNode node2 = new ListNode(2);
        ListNode node3 = new ListNode(4);
        node1.next = node2;
        node2.next = node3;

        // 第二个链表
        ListNode node4 = new ListNode(1);
        ListNode node5 = new ListNode(3);
        ListNode node6 = new ListNode(4);
        node4.next = node5;
        node5.next = node6;

        System.out.println("第一个链表为:");
        show(node1);
        System.out.println("第二个链表为:");
        show(node4);

        ListNode header3 = mergeTwoLists(node1, node4);
        System.out.println("合并后的链表为:");
        show(header3);
    }


    /**
     * 打印链表
     */
    private static void show(ListNode header) {
     
        while (header != null) {
     
            System.out.println(header);
            header = header.next;
        }
    }

    /**
     * 合并链表
     */
    private static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
     
        // 递归的第一步:终止条件,l1 == null,则返回l2。l2 == null,则返回l1。
        if (l1 == null) {
     
            return l2;
        } else if (l2 == null) {
     
            return l1;
        } else if (l1.val < l2.val) {
     
            // 如果 l1 的 val 值更小,则将 l1.next 与排序好的链表头相接。
            l1.next = mergeTwoLists(l1.next, l2);
            return l1;
        } else {
     
            // 如果 l2 的 val 值更小,则将 l2.next 与排序好的链表头相接。
            l2.next = mergeTwoLists(l1, l2.next);
            return l2;
        }
    }
}

2.4 代码分析

LeetCode算法 -- 合并两个有序链表(第7题)_第10张图片

你可能感兴趣的:(数据结构与算法,java,算法,链表,leetcode,数据结构)