【LeetCode-中等-链表】两数相加

这是个关于链表的题目, 以前在C#中写代码时,对链表接触比较少,所以刚好接这个题目来更好的熟悉一下链表

题目大概是这样的,给你两个非空的链表,表示两个非负的整数. 它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字  =》 首先我们来理解这句话是什么意思

我们来看一个链表  1->5->9  看这个链表,有三个节点,每个节点都分别存储了一位数字,第1个节点存储1,指向的是第2个节点(第2个节点存储5),第2个节点指向的是第3个节点(第3个节点存储的是9), 显然这个链表是非空的(非空链表), 满足上面的要求,在看上面一句话 “表示两个非负的整数,它们每位数字都是按照逆序的方式存储的” =》 这句话的啥意思呢,也就是说这个链表是用来表示一个整数的,并且这个整数在链表中是按照逆序的方式存储的,也就是说它表示的这个整数是951,如果是安装链表的指向顺序方式存储就应该是159, 因为是1指向5,5指向9, 现在题目说了每位数字都是按照逆序方式存储的,所以肯定是反过来,也就是951

现在题目要求是这样的:

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

比如  第1个链表 1->7->5   第2个链表 3->5->2  那么第1个链表表示的数字是571  第2个链表表示的数字是253  那么这两个数相加 571 + 253 =  824

所以这个链表表示的是  4->2->8

两个链表也有可能长度不同,比如第1个链表 1->7->4->3->8  第2个链表 3->5->2  那么第1个链表表示的数字是 83471  第2个链表表示的数字是253  那么和是  83471 + 253 =   83724 => 这里要有数学思维,我们用m来表示第1个链表的节点的值,n来表示第2个链表的节点的值

第1个节点: m = 1, n = 3,  m + n = 1+3 = 4

第2个节点: m = 7, n =5,   m + n =  7+5 =12 => 这个节点怎么放呢  节点处存放的值为 (7+5) % 10 = 2 这个节点放的是两个节点值的和除以10的余数(英文中这个单词叫 mod),而进位呢   进位 = (7 + 5) / 10 = 1, 这里英文中我们把进位叫carry, 进位carry是要加到下一个节点中去的, 所以下一个节点的值是 (m + n + carry) % 10 

第3个节点: m = 4, n = 2,还有上一个节点过来的进位carry = 1, 所以 m + n + carry = 4 + 2 + 1 = 7, 节点处存放的值是 (m + n + carry) % 10 = 7

看明白了么,每个节点存放的值都可以说是 (m+n+carry) % 10,  每个节点产生的进位(进位carry是要加到下一个节点中的)是 (m+n+carry) / 10

显然,如果最后一个节点产生的进位carry > 0, 那么它也要加入到下一个节点中,也就是说在最后一个节点后面,会产生一个新的节点,节点的值为最后一个节点产生的carry.  现在我们再来看这个例子

第1个链表 1 -> 7 -> 4->3->8  每个节点的值用m来表示  

第2个链表 3->5->2  每个节点的值用n来表示

第1个节点: m = 1, n = 3, 初始化carry = 0,   节点存放的值 (m + n + carry) % 10 = 4,  该节点产生的进位 carry = (m + n + carry) / 10 = 0

第2个节点: m = 7, n = 5, 来自第1个节点的carry = 0, 所以 节点存放的值为 (7 + 5 + 0) % 10 = 2, 该节点产生的进位 carry = (7+5+0) / 10 = 1

第3个节点: m = 4, n = 2, 来自第2个节点的carry = 1, 所以节点存放的值为 (4 + 2 + 1) % 10 = 7, 该节点产生的进位 carry = (4 + 2 + 1) / 10 = 0

第4个节点: m = 3, n= 0 (第2个链表没有第4个节点了,所以n=0), 来自第3个节点的进位carry = 0, 所以节点存放的值为 ( 3 + 0 + 0) % 10 = 3, 该节点产生的进位carry = (3 + 0 + 0 ) / 10 = 0

第5个节点: m = 8, n =0,来自第4个节点的进位carry=0, 所以节点存放的值为 (8 + 0 + 0) % 10 = 8, 该节点产生的进位carry = (8 + 0 + 0) / 10 = 0

所以这个结果链表表示的是 4->2->7->3->8

 现在我们来写代码,解这道题,我们首先要建立一个单链表的类,在C#里面,它是这样的:

复制代码
public class ListNode
{
public int Val;
public ListNode Next;
public ListNode(int val = 0, ListNode next = null)
{
Val = val;
Next = next;
}
}

public class SumofTwoListNode(ListNode node1, ListNode node2)
{
ListNode head = null; //结果链表的头节点
ListNode tail = null; //结果链表的尾节点
int carry = 0; //初始化进位为0 我刚开始写代码时,把这句写在while循环里面,发现行不通,因为这样,每次循环开始,它都是0,无法更新进位值,所以我们要跳出思维框框,把它的初始化放在while循环外面
while(node1 != null || node2 != null)
{
int node1Value = node1 != null ? node1.Val : 0;
int node2Value = node2 != null ? node2.Val : 0;
// int carry = 0// 刚开始把初始化进位放在这里,发现行不通

            resultNodeValue = (node1Value + node2Value + carry) % 10;
carry = (node1Value + node2Value + carry) / 10; //该节点产生的新进位
           if(head = null) //产生结果链表的第一个节点
{
head = tail = new ListNode(resultNodeValue); //产生的结果链表中的第1个节点,同时作为头节点,也同时作为尾节点
}
else //结果链表中已经有节点了
{
tail.next = new ListNode(resultNodeValue);
tail = tail.next;
}
if(node1 ! = null)
node1 = node1.next;
if(node2 != null)
node2 = node2.next



}
if(carry > 0) //循环完成后,carry还有值,表明需要新增一个节点,节点值为carry
{
tail.next = new ListNode(carry);
}
return head;
}



复制代码

 

  

posted on   新西兰程序员  阅读(21)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示