leetcode是什么意思_LeetCode 第二题 两数相加

4840a4a69767dc3aa729d169158f0e01.png
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807
来源:力扣(LeetCode) 链接: https:// leetcode-cn.com/problem s/add-two-numbers 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这是LeetCode上的第二题,难度是中等,老习惯,先看题干整理出函数头

输入是两条非空链表。链表的数据结构LeetCode已经给出,如下。如果大家对数据结构有兴趣,以后我们也可以增加一些讲数据结构的文章

public class ListNode {
    public int val;
    public ListNode next;
    public ListNode(int x) { val = x; }
}

输出是一条链表,那么很简单,我们的函数头即为

public ListNode AddTwoNumbers(ListNode l1, ListNode l2) 

咱们再看题目要我们做什么吧。链表是按照 逆序 方式存储了两个数字,并且每个节点只有一位数字,意思就是:1234会以 4->3->2->1的形式存储在链表中。

然后将两条链表相加,返回一个同样形式的链表。

那么,大家现在对这道题有什么想法吗?是不是想把这两个链表转化为两个Int然后进行相加。再逐位写入新的链表中,简单快捷。

如果是这样,那么恭喜你,掉进陷阱了。

为什么?因为题目并没有说这个链表是多少位的,它可能有很多位,多到所有数值类型都装不下。

其实我很早就遇到过这道题目,这道题是我大学C++课程期末考试的最后一题。所以这次看到之后就直接想到了解法。其实这个解法的原理很简单,就是咱们小学学过的加法竖式

5c655641300d1662d2458dc7c638ee3d.png

看,有没有瞬间想到了怎么解呢?那么我们就开始一步步用程序来实现竖式的计算过程吧,首先我们先实现两条链表都只有一位的计算,就把9+7给实现以下吧

            ListNode l1 = new ListNode(7);
            ListNode l2 = new ListNode(9);
​
            int l1Val = l1.val;
            int l2Val = l2.val;
            int carry = 0;  //进位
            int temp = l1Val + l2Val + carry;  //上数 加 下数 加 进位
            carry = temp / 10;  //获得进位的数值
            int nodeVal = temp % 10; //获取个位的数值
            ListNode resNode = new ListNode(nodeVal); //这就是加后个位得出的值
​
            l1 = l1.next; l2 = l2.next;//移位,但是我们知道这两个都没有下一位了
​
            if (l1 != null || l2 != null || carry > 0)//判断有没有下一位
            {
                l1Val = l1 == null ? 0 : l1.val; //判断l1链表十位是否为空
                l2Val = l2 == null ? 0 : l2.val; //判断l2链表十位是否为空
​
                temp = l1Val + l2Val + carry;
                resNode.next = new ListNode(temp);//这里我们知道它不会有下一位了
            }
            return resNode;
​
​
​

是不是完全就是小学生的思维模式啊,很简单对不对?

现在只需要将之转化为while 循环即可。这里我们能看出判断是否能继续进行的条件为

if (l1 != null || l2 != null || carry > 0)

那么具体的函数我们就可以构建成

public ListNode AddTwoNumbers(ListNode l1, ListNode l2)
{
    ListNode resNode = new ListNode(-1);//链表头节点,输出的时候这个节点不要
    ListNode currNode = resNode; //当前使用的节点
    int carry = 0;//进位
    int l1Val;  //上数
    int l2Val;  //下数
    int temp;
    while (l1 != null || l2 != null || carry > 0)
    {
        l1Val = l1 == null ?0 : l1.val;
        l2Val = l2 == null ? 0 : l2.val;
​
        temp = l1Val + l2Val + carry;  //上数 加 下数 加 进位
        carry = temp / 10;  //获得进位的数值
​
        currNode.next = new ListNode(temp % 10);//把当前位的值写入链表
        currNode = currNode.next;
​
        l1 = l1 == null ? null : l1.next;
        l2 = l2 == null ? null : l2.next;//移位,但是我们知道这两个都没有下一位了
    }
    return resNode.next;
}

放入LeetCode跑一下

执行用时 :116 ms, 在所有 C# 提交中击败了99.18%的用户

内存消耗 :26.8 MB, 在所有 C# 提交中击败了5.07%的用户

结果还不错。这个算法的时间复杂度是一层循环,次数根据 l1 和 l2 的长度最大值相关 即为 O(max(m,n))

空间上,为结果链表长度 即 l1 和 l2 的长度最大值(+1 可能进位) 即 max(m,n)+1

以上就是LeetCode 第二题的解法了。虽然这道题的难度为中等,但这道题的算法思路是从我们日常生活中来,所以并不觉得很难理解。这也教会我们平时多注意生活中问题的解决方法也是很重要的积累。当然如果大家有更好的解法也可以在留言中告诉我。那么我们下题再见。

8b89a6457026769326dfe4e9298ef787.png
想了解更多,扫码关注我的公众号 IP的dotNet吧
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值