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

本文介绍了递归的基本概念和关键要素,引用了极客时间王争老师的《数据结构与算法之美》专栏,强调了递归在计算机中的优势和人脑理解递归的挑战。通过一个具体的LeetCode问题——合并两个有序链表,展示了如何使用递归方法解决此类问题。代码示例分别给出了C语言和Java的递归解决方案,确保了合并后的链表依然保持升序排列。

递归思路

当时订阅了极客时间王争老师的数据结构与算法之美专栏,总结的非常好

递归需要满足三个条件

  1. 一个问题的解可以分解为几个子问题的解
  2. 这个问题与分解之后的子问题,出来数的规模不同,求解思路完全一样
  3. 存在递归终止条件

总结一下

  1. 写递归代码的关键就是找到如何将大问题分解为小问题的规律,并且基于此写出递推公式,然后再推敲终止条件,最后将递推公式和终止条件翻译成代码
  2. 编写递归代码的关键是,只要遇到递归,我们就把它抽象成一个递推公式,不用想一层层的调用关系,不要试图用人脑去分解递归的每个步骤

注意

  1. 递归代码要警惕堆栈溢出
  2. 递归代码要警惕重复计算
  3. 有时候一个问题要分解为多个子问题的情况,可能不好理解.

王争老师这句话我感觉非常有道理

计算机擅长做重复的事情,所以递归正合它的胃口。而我们人脑更喜欢平铺直叙的思维方式。当我们看到递归时,我们总想把递归平铺展开,脑子里就会循环,一层一层往下调,然后再一层一层返回,试图想搞清楚计算机每一步都是怎么执行的,这样就很容易被绕进去。

题目内容

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

在这里插入图片描述

示例 1:

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

示例 2:

输入:l1 = [], l2 = []
输出:[]

示例 3:

输入:l1 = [], l2 = [0]
输出:[0]

提示:

两个链表的节点数目范围是 [0, 50]
-100 <= Node.val <= 100
l1 和 l2 均按 非递减顺序 排列

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-two-sorted-lists

c语言解答(递归)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
    //如果l1是空的话,返回l2
    if(l1==NULL)
        return l2;
    //如果l2是空的话,返回l1
    if(l2==NULL)
        return l1;
    //如果l1的值小于就让l1的下一个指向下一个最小的,然后找下一个小的,让下一个小的指向下一个小的,这样就发现递归条件了,终止条件也非常好找那就是两个l1和ll2位空的情况.
    if(l1->val<l2->val){
        l1->next=mergeTwoLists(l1->next,l2);
        return l1;
    }
    else{
        l2->next=mergeTwoLists(l1,l2->next);
        return l2;
    }
}

java解答(递归)

/**
 * Definition for singly-linked list.
 * 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; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        //如果l1是空的话,返回l2
        if(l1==null)
            return l2;
        //如果l2是空的话,返回l1
        if(l2==null)
            return l1;
        //如果l1的值小于就让l1的下一个指向下一个最小的,然后找下一个小的,让下一个小的指向下一个小的,这样就发现递归条件了,终止条件也非常好找那就是两个l1和ll2位空的情况.
        if(l1.val<l2.val){
            l1.next=mergeTwoLists(l1.next,l2);
            return l1;
        }
        else{
            l2.next=mergeTwoLists(l1,l2.next);
            return l2;
        }
        }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值