每日一题——两个链表相加

简介: 每日一题——两个链表相加

两个链表相加

题目链接

思考历程(错误解法)

  • 看到这题,我首先想到的就是直接正序相加。
  • 首先创建一个新表头,并让其数据域为零。
  • 要进行正序相加,就必须保证两个链表所代表数字的个、十、百·······位对齐,因此我们就必须计算这连个链表的长度,和他们的长度差,再定义两个指针变量cur1、cur2,使其分别指向表一表二的头,最后让链表较长的cur走count个节点,同时将这些节点的数据域链接到新表(需要新建节点)。
  • 当cur1和cur2对齐后,就可以进行逐位相加了,如果相加的值大于等于10,就向前一位进一 。
  • 做到这里,突然就发现不对了。如果我们只需要进一位,如 5 -> 4 -> 9 这种情况,我们只需要定义一个pre保存前一个节点即可,但如果我们要进位多位,如 5 -> 9 -> 9 -> 9 这种情况,显然这种方法是行不通的。

思路

  • 既然正序相加不行,那我们是否可以考虑逆序相加。
  • 单向链表不能从后往前遍历,所以,我们首先应该反转两个单链表(反转单链表的操作)。
  • 反转过后,显然我们可以发现,两个链表所代表数字的个位、十位、百位······都依次对齐,这样我们就可以直接相加,最后将新链表翻转返回即可。

步骤

  • 翻转两个已知链表。
  • 创建新表头,定义指针变量cur1、cur2、cur3,使其分别指向三个链表的头
  • 定义进位标志flag,如果其为1,就需进位,为0则不需进位
  • 在循环中,创建新节点,其数据域为,(cur1->val + cur2->val + flag) % 10,之后再更新flag,flag = (cur1->val + cur2->val + flag) / 10,最后再让cur1,cur2下滑一个节点
  • 只要cur1、cur2、flag有一个不为假,就说明还没有相加完毕,继续循环
  • 最后,返回新表头的next(新表头没有有效数据)

实现代码

/**
 * struct ListNode {
 *  int val;
 *  struct ListNode *next;
 * };
 */
/**
 * 
 * @param head1 ListNode类 
 * @param head2 ListNode类 
 * @return ListNode类
 */
struct ListNode* FilpLinkList(struct ListNode* phead)      //反转链表
{
    if(!phead)
        return NULL;
  struct ListNode* newHead = (struct ListNode*)malloc(sizeof(struct ListNode));
    struct ListNode* cur = phead;
    newHead->next = phead;
    while(cur->next)
    {
        struct ListNode* temp = cur->next;
        cur->next = temp->next;
        temp->next = newHead->next;
        newHead->next = temp;
    }
    return newHead->next;
}
struct ListNode* CreatNewNode(int num)    //创建新节点
{
    struct ListNode* newNode = (struct ListNode *)malloc(sizeof(struct ListNode));
    newNode->next = NULL;
    newNode->val = num;
    return newNode;
}
struct ListNode* addInList(struct ListNode* head1, struct ListNode* head2 ) {
    if(head1 == NULL || head2 == NULL)    //只要head1、head2有一个为空,就相当于加数为0,直接返回不为空的表头,两个都为空,同理。
        return head1 == NULL ? head2 : head1;
    struct ListNode* head3 = (struct ListNode*)malloc(sizeof(struct ListNode)); //新建表头
    //反转链表
    head1 = FilpLinkList(head1);    
    head2 = FilpLinkList(head2);
    struct ListNode* cur1 = head1, *cur2 = head2,*cur3 = head3;
    int flag = 0,val1,val2;
    while(cur1 || cur2 || flag)
    {
        //如果cur为空,说明已经走到表尾,直接令val为0即可
        val1 = cur1 == NULL ? 0 : cur1->val;
        val2 = cur2 == NULL ? 0 : cur2->val;
        cur3->next = CreatNewNode((val1 + val2 + flag) % 10);   //创建新节点
        flag = (val1 + val2 + flag) / 10;   //更新flag
        cur3 =cur3->next;
        //如果cur为空,则停止下滑
        cur1 = cur1 == NULL ? NULL : cur1->next;
        cur2 = cur2 == NULL ? NULL : cur2->next;
    }
    return FilpLinkList(head3->next); //翻转新表
}


相关文章
|
6月前
|
索引
【力扣刷题】两数求和、移动零、相交链表、反转链表
【力扣刷题】两数求和、移动零、相交链表、反转链表
48 2
【力扣刷题】两数求和、移动零、相交链表、反转链表
|
6月前
|
存储
【每日一题Day254】LC445两数相加Ⅱ | 链表反转 栈
【每日一题Day254】LC445两数相加Ⅱ | 链表反转 栈
44 0
|
6月前
|
存储
【每日一题Day253】LC2两数相加 | 链表模拟
【每日一题Day253】LC2两数相加 | 链表模拟
24 0
|
存储 索引
【Leetcode -141.环形链表 -2.两数相加】
【Leetcode -141.环形链表 -2.两数相加】
27 0
|
6月前
|
存储 算法 索引
【力扣刷题】只出现一次的数字、多数元素、环形链表 II、两数相加
【力扣刷题】只出现一次的数字、多数元素、环形链表 II、两数相加
51 1
|
6月前
|
索引
每日一题:力扣328. 奇偶链表
每日一题:力扣328. 奇偶链表
42 4
(牛客网)链表相加(二)
假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。
54 0
|
6月前
【Leetcode 2807】在链表中插入最大公约数 ——链表|数论
链表插入的基础操作:每次在原链表的相邻两个节点中插入一个新的节点,新节点的值为相邻两个节点的最大公约数,最后返回新的链表即可
|
6月前
|
Java
每日一题《剑指offer》数组篇之数组中的逆序对
每日一题《剑指offer》数组篇之数组中的逆序对
41 0
每日一题《剑指offer》数组篇之数组中的逆序对
|
6月前
|
人工智能 Java
每日一题《剑指offer》数组篇之连续子数组的最大和
每日一题《剑指offer》数组篇之连续子数组的最大和
52 0
每日一题《剑指offer》数组篇之连续子数组的最大和