类型一:链表+数学知识相关的题目-lc2

110 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

lc2

1.先上题解

class Solution {
public:
  ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) {

    //最优解的实现
    //两个使用的遍历指针
    ListNode *p = l1;
    ListNode *q = l2;
    ListNode *res = new ListNode(-1); //结果链表
    ListNode *cur = res;              //结果链表的遍历指针

    int carry = 0; //标志进位
    while (p||q) {
      //获取当前节点的值
      int x = (p) ? p->val : 0;
      int y = (q) ? q->val : 0;
      //数值进行相加
      int sum =
          x + y + carry; //这一步的处理要注意,我们还要记得加上我们的进位的数字
      //将计算的结果插入到链表的尾部
      carry = sum / 10;     //这是进位
      int num = sum % 10; //这时真正的要存的数字
      cur->next = new ListNode(num);
      cur = cur->next;
      //循环链表
      p = p == nullptr ? p : p->next;
      q = q == nullptr ? q : q->next;
    }
    if (carry >
        0) { //此时其实就说明我们最后是有一个进位的,我们要单独新建一个节点来将它衔接上去
      cur->next = new ListNode(carry);
    }
    return res->next;
  }
};

2.思路详解

先读一下题目了解题意

image.png 题目的题意其实已经很清楚了,其实也就是一个数字每一位拆解出来,逆序存到一个链表里,然后我们要做的就是算这样两个链表相加最后将结果也逆序存入一个链表当中。 我们注意下题目中的几个关键条件

  • 数字是逆序的
  • 每一位就存一个数字
  • 开头0问题的定义

2.1 暴力解

暴力解的思路其实是很简单的就是我们可以将链表每个节点的数字取出来,然后我们来做个加法最后我们再将加得得结果再存入链表中,最后将链表结果进行返回,但其实这样做的话我们的缺点也是十分的明显的

  • 首先就是我们知道数字的大小在我们所使用的编程语言当中一般都是有限制的,大数的加法是我们无法避免的,这也是暴力解一个最大的缺点。
  • 其实时间复杂度,空间复杂度都无法达到最优,算法效率十分低下。

2.2最优解

我们来浅谈下最优解代码的实现

其实解法也是很简单的我们的策略就是我们直接定义一个结果链表。然后我们要做的就是对要相加的两个链表来进行一对一加和,并记录好进位,这里可能会运用到大数加法的思想。同时取余,取整的思想也十分经典。

2.3同类题精练

juejin.cn/post/708483…