LeetCode 字符串相加

LeetCode 两数相加

题目1

题目描述

给定两个字符串形式的**非负整数** num1 和num2 ,计算它们的和并同样以字符串形式返回。链接

你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。

分析

由于题目有一下要求:

  • 不能使用任何库函数
  • 不能直接将输入的字符串转换为整数形式

并且如果直接使用数字相加可能出现越界问题,所以我们这里采用最基础的加法思路,即将两个数的对应位依次相加,如下所示,我们需要计算123+48

image-20210925151900427

  • 首先,我们需要将两个数的最低位即个位相加,temp=3+8=11,由于11超过10,需要进位11/10=1,本位**保留** 11%10= 1

  • 接着计算十位,2+4 +1(进位的1)=7

  • 最后计算1**+0(由于没有进位,本位也没有,所以相当于加0)**=1

  • 最终结果即为171

    综上:需要解决以下问题

    • 计算进位:carry = temp / 10
    • 计算结果本位:(n+m+carry)%10
    • 数字索引越界:i >= 0 ? num1.charAt(i) - ‘0’ : 0
    • 循环结束后存在进位: res.append(carry)

解决

public String addStrings(String num1, String num2)
{
    StringBuilder res = new StringBuilder();//记录最终结果
    //记录两个数字的长度
    int i = num1.length() - 1;
    int j = num2.length() - 1;
    //记录进位,初始位为0
    int carry = 0;
    //只要一个数字的还没加完,就继续循环
    while (i >= 0 || j >= 0)
    {
        //从最低位起,将其逐字符转为数字相加
        //如果当前位存在,将其转为数字
        //如果当前位已经不存在,则用0替代
        int n = i >= 0 ? num1.charAt(i) - '0' : 0;
        int m = j >= 0 ? num2.charAt(j) - '0' : 0;
        //记录当前位相加结果(两个相加后再加进位的carry)
        int temp = n + m + carry;
        //更新进位
        carry = temp / 10;
        //拼接当前位结果,只保留个位
        res.append(temp % 10);
        //指针左移
        i--;
        j--;
    }
    //如果循环结束后,标志位不为0,说明还有进位,则需要继续拼接进位
    if (carry != 0)
    {
        res.append(carry);
    }
    //由于是从最低位相加,所以最终拼接后的字符串为结果的逆序,因此需要逆置
    return res.reverse().toString();
}

题目2

题目描述

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。在线OJ

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。image-20210925181050132

题目分析

题目1和题目2几乎相同,只是将字符串变为链表,因此我们只需要更改部分条件即可

  • 由于返回结果为链表,所以定义两个指针,分别保存结果的头和尾
  • 计算结果之前需要拼接字符串并反转,这里只需要添加到结果链表
  • 指针后移时需要判断下一个节点是否为空,如果为空则不需要后移

解决

public ListNode addTwoNumbers(ListNode l1, ListNode l2)
{
    //进位记录,初始化为0
    int carry = 0;
    //定义保存结果链表的头节点和尾结点
    ListNode head = null;
    ListNode tail = null;
    //当有一个链表不为空,继续循环
    while (l1 != null || l2 != null)
    {
        //记录当前节点大小,即对应位大小
        //如果为为空,给0,如果不为空,保存当前节点
        int n = l1 == null ? 0 : l1.val;
        int m = l2 == null ? 0 : l2.val;
        //计算结果
        int temp = n + m + carry;
        //计算进位
        carry = temp / 10;
        //计算本位
        ListNode listNode = new ListNode(temp % 10);
        //拼接结果链表
        if (head == null)//如果头为空,将头节点和尾结点都指向该节点
        {
            head = listNode;
            tail = listNode;
        }
        else//如果头不为空,拼接链表后将尾结点指向该节点
        {
            tail.next = listNode;
            tail = tail.next;
        }
        //指针后移
        if (l1 != null)
        {
            l1 = l1.next;
        }
        if (l2 != null)
        {
            l2 = l2.next;
        }
    }
    //防止循环结束后还存在进位
    if (carry != 0)
    {
        tail.next = new ListNode(carry);
    }
    //返回头节点
    return head;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值