【算法专题--链表】两数相加 -- 高频面试题(图文详解,小白一看就懂!!)

目录

一、前言

二、题目描述 

三、解题方法 

⭐双指针 -- 模拟进位 (使用哨兵位头节点)

🥝 什么是哨兵位头节点?  

🍇思路解析

🍍案例图解 

四、总结与提炼 

五、共勉  


一、前言

       两数相加 这道题,可以说是--链表专题--,最经典的一道题,也是在面试中频率最高的一道题目,通常在面试中,面试官可能会从多个方面考察这道题目,所以大家需要对这道题目非常熟悉哦!!
       本片博客就来详细的讲讲解一下 两数相加 的实现方法,让我们的面试变的更加顺利!!!

二、题目描述 

题目链接:2. 两数相加 - 力扣(LeetCode) 

给你两个 非空 的 链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表

三、解题方法 

⭐双指针 -- 模拟进位 (使用哨兵位头节点)

🥝 什么是哨兵位头节点?  

什么是 哨兵位 头节点? 

  • 它是一个附加的链表结点,该 结点 作为 第一个节点它的数据域不存储任何东西,只是为了操作的方便而引入的。
  • 也就是说,如果一个链表有哨兵节点的话,那么链表表的第一个元素应该是链表的第二个节点。

 哨兵位 --- 头节点的作用:  

  • 比如向链表中插入一个节点,对于没有哨兵位单链表当待插入的节点为链表的第一个节点,由于没有前驱,需要进行特殊处理,从而代码的复杂性增加。 
  • 如果有哨兵位头节点,则第一个节点的处理方式与其它节点相同,可以统一进行处理

🍇思路解析

 题目分析:

一、:给了两个非空的链表,按照逆序的方式存储。OK ,我们先不管他是“逆序”还是“顺序”,对我们来说无所谓。两数相加嘛,很简单的加法计算,因此无论是“逆序”还是“顺序”我们都按照一一对应的位置进行相加就可以了,无所谓顺序如何。

二:问题来了?仅仅是两数相加那么简单吗?如果是 9 + 2 呢?我们难道要输出这位的数字 11吗事实证明,我们要进行——“进位”的操作,这样就满足数学的计算法则了。 

三:说的那么简单,如何进行“进位”这个操作呢?别急~~   先想想,如果我们把 l1 l2 每一位上对应数字 n1、n2 以及进位的数字 rise,三者进行相加 ( n1 + n2 + rise ) ,得到一个“sum”(和),对吧?那么我们对这个”sum“进行 sum / 10 ,这样得到一个数字 C 大家想想这个 C 是不是该位上对下一位的 “进位值” ?


解题思路: 

  • 我们先假设给定的不是链表形式的数字,而是正常的非负整数,则两数相加遵循正常的加法运算,个位数与个位数相加,十位数与十位数相加,如果该位计算结果>9,则向前进位 

  • 那么我们应该怎样取链表中的每一位数字呢?我们定义两个指针,分别指向两个链表的头,然后取出该位置的数字,依次进行计算。 (双指针算法) 

明白上面的大概操作后,肯定还有很多细节没法理解,我们在进行一次图解,让大家更加清楚知道,如何使用双指针 -- 模拟进位


🍍案例图解 

案例图解: l1【2 ,4 ,3】                 l2【5 ,6 ,4】

 

  •  最后,返回 pre_head-> next 即可

 代码:

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) 
    {
        // 创建一个哨兵位节点
        ListNode* pre_head = new ListNode(-1);
        // 指向上述 哨兵位节点 作为当前节点
        ListNode* cur = pre_head;
        
        // 模拟进位  双指针 遍历两个链表

        int rise = 0;  // 保存进位
        while(l1!=nullptr || l2!=nullptr)  //开始遍历两个链表,l1 和 l2 为两个双指针
        {
           int x = l1==nullptr ? 0 : l1->val;
           int y = l2==nullptr ? 0 : l2->val;
            // 求和 ,对应位的数字相加 再加上前一位的进位
            int sum = x + y + rise;

            rise = sum/10;  // 更新进位
            sum = sum%10;   // 保留尾数
            cur->next = new ListNode(sum);

            // 后移
            cur = cur->next;
            if(l1!=nullptr)
            {
                l1 = l1->next;
            }
            if(l2!=nullptr)
            {
                l2 = l2->next;
            }
        }
        // 最后一步加完后 如果有进位
        if(rise == 1)
        {
            cur->next = new ListNode(rise);
        }
        return pre_head->next;
    }
};

 四、总结与提炼 

        最后我们来总结一下本文所介绍的内容,本文讲解来一道力扣中有关 两数相加 的题目,这道题目是校招笔试面试中有关链表章节非常高频的一道题目大家下去一定要自己再画画图,分析一下,把这段代码逻辑自己实现一遍,才能更好地掌握 

五、共勉  

       以下就是我对 两数相加 的理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对 链表专题 的理解,请持续关注我哦!!!  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值