分区:链表

2.两数相加

题目描述:

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

(来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers)

思路与算法

可以看出,两个输入的链表是逆序的,因此两个链表中同一位置的数字可以直接相加。

需要避坑的点:

1、如果两个链表的长度不一样,那对应位置的值该如何加减;

2、对应位置的进位值应该如何处理?我当时想的是判断这轮有没有进位,如果有的话就把链表L1的下一位值通过指针指向val来自加一,但后来发现这样的话当L1加到最后一位这种思路就没办法处理。

3、如何构建两数之和的链表?把对应位置相加之和的值赋给L1(L2也行)的对应位置?还是另外构建一个链表,每次得到对应位置的和之后构建新的结点,然后把该节点连接到新的结点上?答案显然是后者,因为按照前一种方案来的话,按照循环进行操作时,每轮执行的操作应该是相同的,但是L1的长度可能和L2不同,那样的话在L1长度不足的时候就需另外构建结点来保存对应位置的值,然后再接到L1后面,但是这样的操作显然在循环过程中无法格外进行。

解决方案

针对避坑点1:用两个变量n1和n2在每轮循环时分别存储对应位置的值,并且如果在这轮循环中L1为空,但是L2还有值的话,可以利用条件运算符(?:)来使n1为0,这样就可以保证每轮对应位置都有数相加。

int n1 = l1 ? l1->val: 0;
int n2 = l2 ? l2->val: 0;

对于避坑点2:可以用一个变量carry来保存每轮相加的进位值,初始时令carry为0,但每轮循环结束就保存了这轮的进位值,然后作用到下一轮的两数相加中。

//本轮循环
sum = n1+n2+carry;
//......其他操作
carry = sum/10; //用取余操作得到进位值并保存,然后作用于下一轮循环

对于避坑点3:我想的是建立一个链表(带头结点)之后,每次都在循环内用尾插法(常用,最近在复习考研)建立两数值和的单链表,并在返回之前删除头结点,不然不能AC(Accept)。这样的话就需要一个尾指针r来保存最后的结点位置,会耗费空间,但这是我这个本人看了答案之后总结出对自己比较友好记忆的方法,只能这样理解了。而且力扣给的官方解答比较巧妙,相信在比赛的时候我是不会想到的。

ListNode* head=new ListNode(-1); //C++语言建立头结点
ListNode *temp=nullptr,*r=head;  //temp是临时结点,在循环中构建结点用的,r是尾指针,初始时指向头结点//......//将结点插入两数之和的聊表中的操作
temp = new ListNode(sum%10);
r->next=temp;
r=temp;

下面给出官方解答和我的本办法:

官方解答:

class Solution {
public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {ListNode *head = nullptr, *tail = nullptr;int carry = 0;while (l1 || l2) {int n1 = l1 ? l1->val: 0;int n2 = l2 ? l2->val: 0;int sum = n1 + n2 + carry;if (!head) {head = tail = new ListNode(sum % 10);} else {tail->next = new ListNode(sum % 10);tail = tail->next;}carry = sum / 10;if (l1) {l1 = l1->next;}if (l2) {l2 = l2->next;}}if (carry > 0) {tail->next = new ListNode(carry);}return head;}
};

链接:https://leetcode-cn.com/problems/add-two-numbers/solution/liang-shu-xiang-jia-by-leetcode-solution/(求生欲)

我的笨办法:

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {ListNode* head=new ListNode(-1);  //建立头结点,构建两数之和的链表ListNode *temp=nullptr,*r=head;   int carry = 0; int n1,n2;int sum=0;while(l1||l2){       //循环对每轮位置的数相加n1=l1?l1->val:0;   //这种对应位置的处理很巧妙,很多情况都能用到n2=l2?l2->val:0;sum = n1+n2+carry;temp = new ListNode(sum%10);   //取模运算来实现加减进位,这种构建结点的语法见结构体定义//尾插法插入操作r->next=temp;r=temp;carry = sum/10;   //用carry保存每一轮的进位值,并作用到下一轮的计算中//l1指针和l2指针移动操作if(l1){l1=l1->next;}if(l2){l2=l2->next;}}//!!!务必不要忽视对最后carry值的保存!!!if(carry>0){r->next=new ListNode(carry);}head = head->next;   //将头指针指向第一个元素,不要头结点return head;}
};

最后果然的成绩虽然AC了,但这时间空间损耗也说明了我这算法的不友好性。

力扣刷题-单链表两数相加相关推荐

  1. 【leetcode】力扣刷题(2):两数相加(go语言)

    一.问题描述 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表 ...

  2. 力扣刷题——单链表系列——第一题:移除链表元素,从此链表初窥门径,神挡杀神~

    题目链接:力扣 力扣刷题------>单链表系列 第一种解法:在原链表上进行操作,小红日烧脑版 /*** Definition for singly-linked list.* public c ...

  3. 【leetcode】力扣刷题(1):两数之和(Go、Python)

    一.问题描述 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个 ...

  4. 力扣刷题之合并两个有序数组

    力扣刷题之合并两个有序数组 题目 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目. 请你 合并 nu ...

  5. 【菜菜子力扣刷题】1.两数之和

    题目描述 我的代码 /*** Note: The returned array must be malloced, assume caller calls free().*/ int* twoSum( ...

  6. 力扣刷题记录--哈希表相关题目

    当遇到需要快速判断一个元素是否出现在集合里面的时候,可以考虑哈希法,牺牲一定的空间换取查找的时间. java常用的哈希表有HashMap.HashSet以及用数组去模拟哈希,这几种方法各有优劣. 数组 ...

  7. 《剑指Offer》力扣刷题笔记(03-10)

    <剑指Offer>力扣刷题笔记(03-10) 最近确实有点闲,想在进组搬砖之前找点有意义的事干,于是,就开始刷<剑指Offer>.<程序员面试金典>等书上的题目,也 ...

  8. 教你创建电脑、手机同步的markdown云笔记--力扣刷题力荐!

    开篇先致歉 其他不谈,开篇必须先给各位读者道个歉,年后工作上比较忙,加上最近闲暇的时间都用来在力扣上刷算法题了,导致公众号断更有些严重啊.再加上年后将健身减重提上了日程,时间上就更显的捉襟见肘了. 不 ...

  9. 『力扣刷题』5275_找出井字棋的获胜者 解题代码

    LeetCode-cn 力扣刷题 LeetCode-cn力扣刷题目录 165周赛 5275_找出井字棋的获胜者 * 5275. 找出井字棋的获胜者 显示英文描述* 用户通过次数0* 用户尝试次数0* ...

最新文章

  1. python新手菜鸟之基础篇
  2. Spark之伪分布式搭建、伪分布式Hadoop、Hive安装
  3. trident API指南
  4. c语言数据结构kmp中next计算,数据结构——关于KMP算法中next函数的详细解析
  5. 游戏笔记本计算机购买,2021大学生买电脑,容易犯的七种错误!游戏本和轻薄本买哪个?...
  6. linux进程的创建、执行和消亡
  7. 基于ASP的校园二手交易网设计与实现程序免费下载
  8. ashx在web.config中如何配置_网络中,什么是半双工与全双工?它们如何配置
  9. mysql高并发频繁地写_Mysql写入频繁,怎么破?
  10. c语言录屏软件wps,WPS制作录屏视频
  11. 【小程序demo】带你玩转支付宝小程序之小程序二维码
  12. 广州市印发《关于促进大数据发展的实施意见》
  13. Icode编程>>>图形化编程>>>1级训练场>>>基础训练【1】
  14. IDEA 后退/前进 快捷键
  15. Android 接口测方法
  16. GVIM技巧系列-如何在GVIM中跳来跳去
  17. 阿里P8专家年薪170万IT男征婚被嘲讽?钱不是万能的!
  18. 基础五:光的量子纠缠
  19. 交互式系统中采用的调度算法
  20. stm32使用dsp库,结合Matlab进行FIR滤波器设计

热门文章

  1. 面试官:MySQL索引底层数据结构原理与性能调优,你能回答多少?
  2. 这个小程序厉害了!一键生成花式昵称,让你的微信从此与众不同!
  3. Android之短信验证码
  4. java 计算均值和标准差_java计算方差、标准差(均方差)实例代码
  5. 如何使特定的数据高亮显示?
  6. GBase基本查询操作
  7. Spring的作用域与生命周期
  8. testlink linux,Linux下安装testlink
  9. 前端开发审查元素时CSS样式有个横线(该CSS样式定义后无效) 的解决办法
  10. RxSwift之路01-----简单的RxSwift使用