0
点赞
收藏
分享

微信扫一扫

【LeetCode】No.2. Add Two Numbers -- Java Version

yellowone 2022-04-02 阅读 31

题目链接: https://leetcode.com/problems/add-two-numbers/

1. 题目介绍(链表相加)

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list.

【Translate】: 给定两个非空链表,表示两个非负整数。数字在链表中按照倒序存储,每个节点包含一个数字。将这两个数字相加,最后以链表的形式返回总和。

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

【Translate】: 你可以假设这两个数字不包含任何前导零(eg:0011),除了数字0本身。

测试用例:
testcase1
testcase2
约束:
Constraints

2. 题解

2.1 只适合9节点以下的链表

  拿到这个题,就想着怎么莽了。不过最后发现小丑是我自己,这一题还真不能莽着来。下方代码的思路非常简单,先把l1l2两个链表中的数循环遍历还原相加,得到它所表示的数值,并用一个数组将它们记录下来。之后将两个数相加,声明头节点、当前节点和一个临时节点用来切割相加后的数字,但这样做的缺点非常明显,int数值是2的32次方 = 4294967296,一旦数字超过了这个范围就会出错。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers1(ListNode l1, ListNode l2) {
        int temp = 0;
        int[] nums = new int[3];
        for(int i = 0; l1 != null; i++){
            temp = l1.val * (int)Math.pow(10, i);
            nums[0] += temp; 
            l1 = l1.next;
        }
        for(int i = 0; l2 != null; i++){
            temp = l2.val * (int)Math.pow(10, i);
            nums[1] += temp; 
            l2 = l2.next;
        }
        int sum = nums[0]+nums[1];
        nums[2] = (sum+"").length();
        int[] tempArr = new int[nums[2]+1]; 
        ListNode head = new ListNode();
        ListNode curr = new ListNode();
        ListNode tempNode = new ListNode();
        for(int i = nums[2]-1; i >= 0; i--){
            temp = sum / (int)Math.pow(10, i);
            System.out.println(temp);
            sum = sum % (int)Math.pow(10, i);
            tempArr[i] = temp;   
        }
        
        for(int i = 0; i < nums[2]; i++){
            if(i == 0 && nums[2] == 1){
                head.val = tempArr[i];
                curr = head;
                return head;
            }
            if(i == 0){
                head.val = tempArr[i];
                curr = head;
            }else{
                tempNode = new ListNode(tempArr[i]);
                curr.next = tempNode;
                curr = curr.next;
            }      
        }
        return head;
    }
    

result1

2.2 O(max(m,n))

  【Solution】就像你在一张纸上对两个数字求和一样,我们从最低有效数开始求和,也就是l1和l2的头。由于每个数字都在0…9的范围内,两个数字相加可能会“溢出”。例如5+7= 12。在本例中,我们将当前数字设置为2,并将carry= 1带到下一次迭代中。进位必须是0或1,因为两个数字(包括进位)的最大可能和是9+9+1= 19。
  和这个题解一对比,我发现我真的是too young,too simple。在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 != 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;
}

case2

3. 可参考

[1] 遇到的int型数字越界的情况
[2] Lossy Conversion in Java
[3] 关于出现incompatible types: possible lossy conversion from long to int错误(类型转化错误)

举报

相关推荐

0 条评论