力扣 2.两数相加

题目传送门
题意:这个题的题意很简单就是给两个链表,这两个链表存储的是两个数字的逆序,需要你求这两个数的和,并且存进链表中,并且是逆序存储,例如题目给的样例[2,4,3],[5,6,4],那这两个数就是342和465,他们的和就是807,输出[7,0,8],题意很简单,问题也不难,但是我这个小菜鸡错了很多遍。并且看这个题,这个题也给了我们一种大数求和的思路,可以将两个大数可以存储进单链表,然后分位求和。
上代码:(后面会给上讲解,和我掉的坑,我是大菜鸡)

/**
 * 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* l3;
         ListNode* p=new ListNode(0);
         l3=p;
         while(l1->next&&l2->next){
    
    
             ListNode* q=new ListNode(0);//用来存储进位,以及下一位
             q->val=(p->val+l1->val+l2->val)/10;//进位
             p->val=(p->val+l1->val+l2->val)%10; //注意要+p->val,要考虑是否有进位
             l1=l1->next;
             l2=l2->next;
             p->next=q;
             p=q;
         }
         ListNode* q=new ListNode(0);
         q->val=(p->val+l1->val+l2->val)/10;
         p->val=(p->val+l1->val+l2->val)%10;
         l1=l1->next;
         l2=l2->next;
         if(q->val||l1||l2){
    
     //是否有进位,l1和l2是否有剩余位
             p->next=q;
             p=q;
         }
         while(l1){
    
    
             ListNode* q=new ListNode(0);
             q->val=(p->val+l1->val)/10;
             p->val=(p->val+l1->val)%10;
             if(l1->next||q->val){
    
    
                p->next=q;
                l1=l1->next;
                p=q;
             }else{
    
    
                 break;
             }  
         }
         while(l2){
    
    
             ListNode* q=new ListNode(0);
             q->val=(p->val+l2->val)/10;
             p->val=(p->val+l2->val)%10;
             if(l2->next||q->val){
    
    
                 p->next=q;
                 l2=l2->next;
                 p=q;
             }else{
    
    
                 break;
             } 
         }
         return l3;
    }
};

知识点回顾:
其实第一眼看这个题,我先去回顾了一下单链表的操作,毕竟我是一个菜鸡,首先什么是单链表,单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据(百度百科)。也就是说单链表就是相同类型的结构体通过指针连成的链式结构,列如这个题的链表声明:

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) {
    
    }
   };

val是里面的元素,next是指向下一个结构体的指针,那么该如何操作里面的数据呢,这个时候,我们就需要一个神奇的符号:->,这个符号可以帮助我们来操纵里面的数据,例如,我想要用val的值,我就可以p->val,p就是一个结构体对象,我想要p连接的下一个呢?就可以p=p->next;就是这么神奇,知道这么多就可以解决这个问题了,但是链表的知识还有很多,不仅仅是这些皮毛。
这个结构体里面还有一些神奇的东西,就是:
在这里插入图片描述
就是这些构造函数,很神奇,然后我就在想,结构体里面有元素还有函数方法,Class类里面也有,这样看,两者很相似。但是既然C++里面同时含有这两个,那就说明他们他们还是有区别,在用途上还是有区别的。(菜鸡很菜,还说不出两者,希望未来可以)
我踩得坑:
第一坑:这个题的思路就是每一位的数相加,取和的个位,把十位进位,我第一遍错是因为我在插入一个节点的时候没有更新指针,使得每一位的结果都存到了同一个结构体里面,也就是没有构成链式结构,少了p->q这句代码,然后我的结果就只有两位。
第二坑:我在从第一个坑出来之后,马上就掉进了第二个坑,第二个坑主要因为循环条件,我开始的循环条件是while(l1&&l2),那这就导致了一个问题,我输出的结果多输出了一个0,因为我在进行最后的运算的时候,可能没有进位,
q->val=0,那么这个时候就不需要在让p=q,但是我掉坑里了。
第三坑:
在这里插入图片描述
在这里插入图片描述
第三个坑主要是因为这个if判断,里面的条件不全面,在最后一位元素的运算要考虑具体条件,是否进位,是否需要p=q;
**总结:**考虑问题要全面,要考虑所有情况。

如果有大佬看到这篇文章,有问题希望指教,感谢。

Guess you like

Origin blog.csdn.net/qq_43840681/article/details/117304808