LeetCodeTop100(2):两数相加

1. 题目描述

给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储 一位数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

来源:力扣(LeetCode)
原题传送门:link.

2. 考察知识点

链表

3. 思路
  1. 我们需要模拟两数相加的过程,创建第三个链表存储第一个和第二个链表的和。由于是逆序的方式,起始为个位数,无需考虑翻转链表。
  2. 难点是进位是的操作,我们需要清楚以下几点:
  • 同位相加时,若大于等于10,那么此位只存储结果的个位并进位。
  • 同位相加时,需要先考虑是否有进位,再相加。
  • 还需要考虑两个链表若不等长的情况。
  1. 具体可看代码注释。
4. 代码(Java)
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
 class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    ListNode dummyHead = new ListNode(0);//新建一个链表存储
    ListNode p = l1, q = l2, curr = dummyHead;//三个指针指向头结点
    int carry = 0;
    while (p != null && q != null) {
        int x = p.val;
        int y =q.val;
        int sum = carry + x + y;//p相加求值
        carry = sum / 10;//因为carry是整型,如果sum大于10那么,carry 就会等于1
        curr.next = new ListNode(sum % 10);//因为之前只创建了一个头结点,所以此处需要先创建新节点再赋值
        curr = curr.next;//指针后移
        p = p.next;
        q = q.next;
    }
   if(p != null)//当两个链表不等长时进行如下操作
   p.val+=(carry>0)?1:0;
   curr.next = p;
   if(q != null)
   q.val+=(carry>0)?1:0;
   curr.next = q;
   return dummyHead.next;
}
 }
5. 时间及空间复杂度
  • 时间复杂度:O(max(m,n)),假设 m和 n分别表示 l1 和 l2 的长度,上面的算法最多重复max(m,n) 次。

  • 空间复杂度:OO(max(m,n)), 新列表的长度最多为max(m,n)+1。

6. 知识积累
ListNode dummyHead = new ListNode(0);

上述命令只建了一个值为0的头结点,若扩展需要新建结点:

curr.next = new ListNode(sum % 10);

你可能感兴趣的:(链表,java,leetcode,数据结构,算法)