本文主要用于记录刷力扣的题解,因为自己算法太菜,所以想通过深度学习力扣的每一道题目的原理来提高自己。
下面内容为自己学习时的记录,如有错误,欢迎指正
文章目录
- LEETCODE的第二题——两数相加(链表)
- 一、 题目——2.两数相加
- 二、思路
- 链表
- 三、题解
- 1.使用python进行题解
- 2.使用C语言题解
先来看一下题目吧,这个题目被评为中等难度,我觉得是因为这个题目需要用到链表,不能直接使用一些简单的C语言就可以解(虽然我是使用python解的)
题目是需要我们模拟手工相加两个
逆序
链表代表的数字。
- 首先我们需要知道创建链表(虽然很废,但是对链表不太熟悉的伙伴,创建链表还是需要去回忆的)
- 开始相加:从链表的头部开始遍历两个来年表,逐位相加,并考虑进位。
- 结果存储在新链表中,新链表的每一个节点都代表相加后的数字的一位。
- 需要考虑的是,如果两个链表的长度不一样,则需要考虑其中一个链表已经遍历完的情况。同时如果最高位有进位,需要将进位添加到新链表的末尾。
链表是一种常见的数据结构,用于存储和组织一系列数据元素,这些元素通过节点(Node)连接在一起。每个节点包含两个部分:
数据
(通常是一个值)和指向下一个节点的引用或指针
。
主要的链表类型包括:
单链表(Singly Linked List):每个节点包含数据和指向下一个节点的指针。最后一个节点的指针通常指向空(None或null)。
1 -> 2 -> 3 -> 4 -> None
双链表(Doubly Linked List):每个节点包含数据、指向下一个节点的指针和指向前一个节点的指针。这使得在双链表中可以更方便地进行双向遍历。
None <- 1 <-> 2 <-> 3 <-> 4 -> None
循环链表(Circular Linked List):最后一个节点的指针不是空,而是指向链表的头节点,从而形成一个循环。
1 -> 2 -> 3 -> 4 -> 1
链表的优点:
动态内存分配
:链表可以根据需要动态分配内存,因此在插入和删除元素时更加灵活。空间效率
:链表只分配所需的内存,不浪费空间。链表的缺点:
随机访问效率较低
:要访问链表中的任何元素,必须从头开始遍历,直到找到目标元素。需要额外的内存空间
:每个节点需要额外的指针来存储下一个节点的地址,可能会增加内存消耗。链表常用于实现栈、队列以及各种高级数据结构,以及在内存动态管理和大数据处理等领域。
# 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]:
head=ListNode() #创建一个新的链表节点,用于表示链表的头部
current=head
carry=0#表示进位的变量
while l1 or l2 or carry:#只要两者都非空
x=l1.val if l1 else 0 #获取当前节点(如果为空则=0)
y=l2.val if l2 else 0
total_sum=x+y+carry
carry=total_sum//10 #计算新的进位
current.next=ListNode(total_sum%10)
current=current.next
if l1:
l1=l1.next
if l2:
l2=l2.next
return head.next
部分代码解释
代码中,def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]
中的Optionnal[ListNode]
是Solution类中的方法定义,名字为addTwoNumbers
.
self
:这是一个特殊的参数,表示类的实例自身。在Python中,类的方法第一个参数通常为 self,用于访问类的成员变量和其他方法。
l1: Optional[ListNode]
:这是一个参数,表示第一个链表 l1,类型注解 Optional[ListNode] 表示参数可以是链表节点类型或None。
l2: Optional[ListNode]
:这是第二个参数,表示第二个链表 l2,也可以是链表节点类型或None。
-> Optional[ListNode]
:这是返回值的类型注解,指定了该方法应该返回一个链表节点类型或None。
之所以还要复现一次C语言的算法实现,是为了更好的熟悉算法思路(因为我自己是更加熟悉C语言的)
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
struct ListNode *head = NULL,*tail=NULL;
int carry = 0;
while (l1||l2){
int n1=l1 ? l1->val :0 ;
int n2=n2 ? l2->val :0;
int sum =n1+n2+carry;
if(!carry){
head=tail =malloc(sizeof(struct ListNode));
tail->vail=sum%10;
tail->next=NULL;
}
else{
tail->next =malloc(sizeof(struct ListNode));
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;
}
}
写在最后:
代码为leetcode官方提供
本文只为个人学习记录★,°:.☆( ̄▽ ̄)/$:.°★ 。