LeeCode 02: 两数相加

139 阅读3分钟

题目描述

给定两个非负整数(以链表形式表示),每个节点包含一个数字,这些数字按照逆序的方式存储,即链表的第一个节点包含数字的个位,链表的最后一个节点包含数字的最高位。编写一个函数,将这两个数相加,并以链表形式返回它们的和。

image.png

题目分析

这个问题要求我们将两个以链表形式表示的非负整数相加。由于数字是逆序存储的,我们可以从链表的头部开始,逐位相加,并处理进位。这个问题涉及到的主要知识点包括链表的基本操作(如遍历、创建节点)、基本的算术运算以及进位处理。

解题思路

  1. 初始化:创建一个哑节点(dummy node)作为结果链表的头部,这样可以简化边界条件的处理。同时,初始化一个进位变量 carry 为 0。

  2. 遍历链表:同时遍历两个输入链表,直到它们都遍历完。在每一步中,执行以下操作:

    • 获取当前两个节点的值(如果某个链表已经遍历完,则将其值视为 0)。
    • 将这两个值和进位相加,得到当前位的和。
    • 创建一个新的节点,将和的个位数作为新节点的值,并将新节点链接到结果链表的末尾。
    • 更新进位为和的十位数。
    • 如果某个链表还有剩余节点,则继续遍历该链表,并将进位与当前节点的值相加,重复上述步骤。
  3. 处理最后的进位:如果遍历完两个链表后,进位仍然大于 0,则需要在结果链表的末尾添加一个值为进位的节点。

  4. 返回结果:返回哑节点的下一个节点作为结果链表的头节点(因为哑节点本身不存储有效数据)。

涉及到的知识难点

  1. 链表的基本操作:包括创建节点、遍历链表、在链表末尾添加节点等。这是解决链表相关问题的基础。
  2. 算术运算与进位处理:在加法运算中,需要正确处理每一位的和以及进位。特别是当链表长度不一致时,需要将较短的链表视为在末尾有若干个 0 的链表。
  3. 边界条件处理:例如,当两个链表都遍历完后,如果进位仍然大于 0,则需要在结果链表的末尾添加一个值为进位的节点。此外,还需要注意空链表或只包含一个节点的特殊情况。
  4. 内存管理:在某些编程语言中(如C或C++),需要手动管理内存,包括为链表节点分配和释放内存。然而,在像JavaScript或Python这样的高级语言中,内存管理是由垃圾回收器自动完成的。

示例代码(JavaScript)

	class ListNode {
	    constructor(val = 0, next = null) {
	        this.val = val;
	        this.next = next;
	    }
	}

	function addTwoNumbers(l1, l2) {
	    let dummy = new ListNode(0); // 哑节点
	    let curr = dummy; // 当前操作节点
	    let carry = 0; // 进位
	  
	    while (l1 || l2) {
	        const x = l1 ? l1.val : 0;
	        const y = l2 ? l2.val : 0;
	        const sum = carry + x + y;
	        carry = Math.floor(sum / 10); // 更新进位
	        curr.next = new ListNode(sum % 10); // 创建新节点并链接到结果链表
	        curr = curr.next; // 移动到下一个节点

	        if (l1) {
	            l1 = l1.next;
	        }
	        if (l2) {
	            l2 = l2.next;
	        }
	    }

	    if (carry > 0) {
	        curr.next = new ListNode(carry); // 如果最后还有进位,则添加到结果链表末尾
	    }

	    return dummy.next; // 返回哑节点的下一个节点作为结果链表的头节点
	}

总结

这道题目,主要就是链表相关的知识点,还是要好好学习下相关内容再来解题。希望这篇分享能够帮助大家更好地理解和解决类似的问题。