4.12每日一练

题目:给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/add-two-numbers
4.12每日一练_第1张图片
思路其实很简单
两个列表,因为是逆序,对应相加,多的进位就好了
直接上代码

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


struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
    struct ListNode*head=NULL;
    struct ListNode*tail=NULL;
    struct  ListNode*tmp=NULL;
    int carry=0;
    while(l1||l2)
    {
        int n1=l1?l1->val:0;
        int n2=l2?l2->val:0;
        int sum= n1+n2+carry;
        先做三目运算再赋值
        tmp=malloc(sizeof(struct ListNode));
        memset(tmp,0,sizeof(struct ListNode));这里我做个了检测并给了一个初始化
        毕竟学安全的
        写的代码还是要注意一下安全性
        if(tmp==NULL)
        {
            return 1;
        }
        if(head==NULL)
        {
           head=tail=tmp;
           tail->val=sum%10;
           tail->next=NULL; 
        }
        else
        {
            tail->next=tmp;
            tail->next->val=sum%10;
            tail=tail->next;
            tail->next=NULL;
        }
        carry=sum/10;
        if(l1)
        {
            l1=l1->next;
        }
        if(l2)
        {
            l2=l2->next;
        }
    }
    if (carry > 0) {
        tail->next = tmp;
        tail->next->val = carry;
        tail->next->next = NULL;
    }
    return head;
 
}

OK当你运行这个代码的时候一定会报错
4.12每日一练_第2张图片
为什么少了一个0?因为看最后一段tmp给的空间有问题

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


struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
    struct ListNode*head=NULL;
    struct ListNode*tail=NULL;
    struct  ListNode*tmp=NULL;
    int carry=0;
    while(l1||l2)
    {
        int n1=l1?l1->val:0;
        int n2=l2?l2->val:0;
        int sum= n1+n2+carry;
        //先做三目运算再赋值
        tmp=malloc(sizeof(struct ListNode));
        memset(tmp,0,sizeof(struct ListNode));
        if(tmp==NULL)
        {
            return 1;
        }
        if(head==NULL)
        {
           head=tail=tmp;
           tail->val=sum%10;
           tail->next=NULL; 
        }
        else
        {
            tail->next=tmp;
            tail->next->val=sum%10;
            tail=tail->next;
            tail->next=NULL;
        }
        carry=sum/10;
        if(l1)
        {
            l1=l1->next;
        }
        if(l2)
        {
            l2=l2->next;
        }
    }
    if (carry > 0) {
        tail->next =malloc(sizeof(struct ListNode)); ;
        tail->next->val = carry;
        tail->next->next = NULL;
    }
    return head;
 
}

把最后申请空间这里改改就好了
看看python代码,python有很多还没学
这里记录一下

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        if not l1:
            return l2
        if not l2:
            return l1

        l1.val += l2.val    # 将两数相加,赋值给 l1 节点
        if l1.val >= 10:
            l1.next = self.addTwoNumbers(ListNode(l1.val // 10), l1.next)
            l1.val %= 10
        
        l1.next = self.addTwoNumbers(l1.next, l2.next)
        return l1



作者:pedantic-shamiruww
链接:https://leetcode.cn/problems/add-two-numbers/solution/by-pedantic-shamiruww-p9h3/

这里是使用了一个递归算法
什么是递归?
在计算机导论里面学过,就不说了(调用自身函数)
https://blog.csdn.net/lltqyl/article/details/106604387

这里再说一种,用迭代法

struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
 struct ListNode* res = (struct ListNode*)malloc(sizeof(struct ListNode));用一个哑节点(dummy node)提供迭代的初始参数;
 res->val = 0;
 res->next = NULL;
 struct ListNode* pre = res;
 int carry = 0;
 while (l1 || l2 || carry)只要有一个存在迭代就可以继续;
 {
  struct ListNode* temp = (struct ListNode*)malloc(sizeof(struct ListNode));
  int n1 = l1 ? l1->val : 0;
  int n2 = l2 ? l2->val : 0;
  int sum = n1 + n2 + carry;

  temp->val = sum % 10;
  temp->next = NULL;
  pre->next = temp;
  以上三行代码为新节点各域(数据域和指针域)赋值,并放置于前驱节点之后;

  pre = pre->next;
  carry = sum / 10;
  l1 = l1 ? l1->next : NULL;
  l2 = l2 ? l2->next : NULL;
  以上四行代码更新四个迭代参数;
 }
 return res->next;
}
作者:sui-xin-nt
https://leetcode.cn/problems/add-two-numbers/solution/chun-cxie-fa-1die-dai-xie-fa-by-sui-xin-7apuf/
这写得是真可以,我是没想出来

什么是迭代https://blog.csdn.net/qq_61453770/article/details/122812914?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168130018716800186539845%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=168130018716800186539845&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-122812914-null-null.142v83pc_search_v2,201v4add_ask,239v2insert_chatgpt&utm_term=%E8%BF%AD%E4%BB%A3%E7%AE%97%E6%B3%95&spm=1018.2226.3001.4187
记住:迭代的效率比递归高,尤其是计算次数多的时候

你可能感兴趣的:(每日练习,学习,leetcode)