链表求和问题——炼码221 · 链表求和 II

目录

题目

解析

代码


题目

描述

假定用链表表示两个数,其中每个节点仅包含一个数字。假设这两个数的数字顺序排列,请设计一种方法将两个数相加,并将其结果表现为链表的形式。

样例

样例 1:

输入: 6->1->7   2->9->5
输出: 9->1->2

样例 2:

输入: 1->2->3   4->5->6
输出: 5->7->9

解析

 最开始我的想法是将两个链表转化为数字,然后相加,最后再将相加的那个值转化为字符串,但是当链表过长时,会导致溢出,链表转化出来的数字超过了int和longlong的范围。不能过所有的样例。

/**
 * Definition of singly-linked-list:
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *        this->val = val;
 *        this->next = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param l1: The first list.
     * @param l2: The second list.
     * @return: the sum list of l1 and l2.
     */
    ListNode* addLists2(ListNode *l1, ListNode *l2) {
        long long num1 = 0,num2 = 0;
        while(l1) {
            num1 = num1 * 10 + l1 -> val;
            l1 = l1 -> next;
        }
        while(l2) {
            num2 = num2 * 10 + l2 -> val;
            l2 = l2 -> next;
        }
        //先计算出l1和l2的大小
        long long num3 = num1 + num2;
        //l3的大小,再将它转化为一条链表即可
        string l3s = to_string(num3);
        ListNode* p = new ListNode(0);
        ListNode* head = p;
        for (char c : l3s) {
            p->next = new ListNode(c - '0');
            p = p->next;
        }
        return head->next;
        // write your code here
    }
};

然后进行了更改,不将链表转化为数字,而是转化为字符串然后再进行大数相加,再将最后得到的字符串转化为链表即可。 这样可以避免转化为整数而导致的溢出错误。

  1. 链表转字符串

    • 直接遍历链表,将每个节点的值拼成字符串,保留原始高位顺序(例如 2->8->2 转为 "282")。

  2. 字符串大数相加

    • 从最低位(字符串末尾)开始逐位相加,处理进位。

    • 结果需要反转,因为加法是从低位到高位计算的。

  3. 字符串转链表

    • 按照字符串顺序直接创建链表,保持高位在前。

  4. 时间复杂度:O(max(m,n)),其中 m 和 n 是链表长度。

代码

/**
 * Definition of singly-linked-list:
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *        this->val = val;
 *        this->next = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param l1: The first list.
     * @param l2: The second list.
     * @return: the sum list of l1 and l2.
     */
    // 将链表转为字符串(高位在前)
    string listToString(ListNode* head) {
        string s;
        while (head) {
            s += to_string(head->val);
            head = head->next;
        }
        return s;
    }

 // 大数相加(字符串处理)
    string addStrings(string num1, string num2) {
        int i = num1.size()-1, j = num2.size()-1;
        int carry = 0;
        string res;
        while (i >= 0 || j >= 0 || carry > 0) {
            int n1 = (i >= 0) ? (num1[i--] - '0') : 0;
            int n2 = (j >= 0) ? (num2[j--] - '0') : 0;
            int sum = n1 + n2 + carry;
            res.push_back(sum % 10 + '0');
            carry = sum / 10;
        }
        reverse(res.begin(), res.end()); // 结果需要反转
        return res;
    }

 // 将字符串转为链表(高位在前)
    ListNode* stringToList(const string& s) {
        ListNode* dummy = new ListNode(0);
        ListNode* curr = dummy;
        for (char c : s) {
            curr->next = new ListNode(c - '0');
            curr = curr->next;
        }
        return dummy->next;
    }

    ListNode* addLists2(ListNode *l1, ListNode *l2) {
        string s1 = listToString(l1);
        string s2 = listToString(l2);
        string sum = addStrings(s1, s2);
        return stringToList(sum);
        // write your code here
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柏箱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值