给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。 1.Java 知识准备:链表相关知识: 链表的初始化:
public class Node<T> { public T data; public Node next; public Node(T data) { this.data = data; } }链表的相关操作: 2.本题答案 方法1:官方给出的思路是利用初等数学的方法,
java 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 != null) ? p.val : 0; int y = (q != null) ? q.val : 0; int sum = carry + x + y; carry = sum / 10; curr.next = new ListNode(sum % 10); curr = curr.next; if (p != null) p = p.next; if (q != null) q = q.next; } if (carry > 0) { curr.next = new ListNode(carry); } return dummyHead.next; } ```方法2:链表
/** * 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 pre = new ListNode(0); ListNode cur = pre; int carry = 0; while(l1 != null || l2 != null) { int x = l1 == null ? 0 : l1.val; int y = l2 == null ? 0 : l2.val; int sum = x + y + carry; carry = sum / 10; sum = sum % 10; cur.next = new ListNode(sum); cur = cur.next; if(l1 != null) l1 = l1.next; if(l2 != null) l2 = l2.next; } if(carry == 1) { cur.next = new ListNode(carry); } return pre.next; } } public class Solution { /// <summary> /// 累加两个数字(链表表示) /// </summary> /// <param name="l1">数字1</param> /// <param name="l2">数字2</param> /// <returns>两数之和(链表表示)</returns> public ListNode AddTwoNumbers(ListNode l1, ListNode l2) { ListNode resultRoot = GetLongestList(l1, l2); //优化1:使用较长的一个数字空间来存储结果,减少内存分配 int overNumber = 0; //上一位数计算后的进位 ListNode currentResultNode = resultRoot; //初始化当前计算位数结果位(个位) ListNode lastNodeBackup = currentResultNode; //最后计算位数(最高位)位置备份 ListNode p_l1 = l1; //初始化数字1和数字2当前计算位数 ListNode p_l2 = l2; while (p_l1 != null || p_l2 != null || overNumber > 0) { int currentResult = (p_l1?.val ?? 0) + (p_l2?.val ?? 0) + overNumber; int realResult = currentResult % 10; currentResultNode.val = realResult; overNumber = currentResult == realResult ? 0 : 1; p_l1 = p_l1?.next; p_l2 = p_l2?.next; //优化2:如果其中一个数字较长,且与较短数字的所有位已计算完毕,且无进位,则将较长数字的后续位直接接到结果末尾,无需计算 if (p_l1 == null && p_l2 != null && overNumber == 0) { currentResultNode.next = p_l2; return resultRoot; } else if (p_l1 != null && p_l2 == null && overNumber == 0) { currentResultNode.next = p_l1; return resultRoot; } else { if (currentResultNode.next == null) { currentResultNode.next = new ListNode(0); } lastNodeBackup = currentResultNode; currentResultNode = currentResultNode.next; } } if (lastNodeBackup.next != null && lastNodeBackup.next.val == 0) { lastNodeBackup.next = null; //清除多余的0节点 } return resultRoot; } /// <summary> /// 返回较长的链表数字 /// </summary> /// <param name="l1">数字1</param> /// <param name="l2">数字2</param> /// <returns>两个数字中较长的数字</returns> private ListNode GetLongestList(ListNode l1, ListNode l2) { ListNode p_l1 = l1.next; ListNode p_l2 = l2.next; while (true) { if (p_l1 == null) { return l2; } else if (p_l2 == null) { return l1; } else { p_l1 = p_l1.next; p_l2 = p_l2.next; } } } }