题解 | 链表操作|#链表相加(二)#

链表相加(二)_牛客题霸_牛客网

这个问题主要涉及一个链表的原地掉头问题,和链表的边界问题。

一、使用指针组实现原地掉头

在这里我抛弃了前文中使用插入方式的链表转向,转用指针组扫描的方式用原地掉头实现链表转向。

具体思路为使用三个指针扫描过所有链表,将下一个节点的指针调转,使其指向上一个节点

其中A指针指向需要指向的目标节点、B指针指向需要转向的节点、C指针则指引指针组的前进方向。注意分类讨论链表长度造成的差异。

ListNode *turnDown(ListNode *head)
{
    if (head == nullptr) {
        return nullptr;
    } else if (head->next == nullptr) {
        return head;
    } else if (head->next->next == nullptr) {
        ListNode* p = head->next;
        head->next = nullptr;
        p->next = head;
        head = p;
        return head;
    } else {
        ListNode* a, *b, *c;
        a = head;
        b = head->next;
        c = head->next->next;
        a->next = nullptr;
        while (c != nullptr) {
            b->next = a;
            a = b;
            b = c;
            c = c->next;
        }
        b->next = a;
        head = b;
        return head;
    }
    return nullptr;
}

二、进行逐节点相加和进位

有了链表原地掉头功能后我们就可以把目标链表进行掉头,随后又左向右进行相加进位。

注意要考虑两个节点不同结束的情况和节点为空之后的补全情况。

    ListNode* addInList(ListNode* head1, ListNode* head2) {
        // write code here
         ListNode* l,*lh;
            l= turnDown(head1);
            lh= l;
            ListNode* r,*rh;
            r = turnDown(head2);
            rh= r;
            int i = 0;
            while (l != nullptr || r != nullptr) {
                if (l->next != nullptr && r->next != nullptr) {
                    int a = l->val;
                    int b = r->val;
                    l->val = r->val = (a + b + i) % 10;
                    i = (a + b + i) / 10;
                    l = l->next;
                    r = r->next;
                } else if (l->next == nullptr && r->next != nullptr) {
                    int a = l->val;
                    int b = r->val;
                    l->val = r->val = (a + b + i) % 10;
                    i = (a + b + i) / 10;
                    ListNode* it = new ListNode(0);
                    it->next = nullptr;
                    l->next = it;
                    l = l->next;
                    r = r->next;

                } else if (l->next != nullptr && r->next == nullptr) {
                    int a = l->val;
                    int b = r->val;
                    l->val = r->val = (a + b + i) % 10;
                    i = (a + b + i) / 10;
                    ListNode* it = new ListNode(0);
                    it->next = nullptr;
                    r->next = it;
                    l = l->next;
                    r = r->next;

                } else if (l->next == nullptr && r->next == nullptr) {
                    int a = l->val;
                    int b = r->val;
                    l->val = r->val = (a + b + i) % 10;
                    i = (a + b + i) / 10;
                    if (i == 0) {
                        lh = turnDown(lh);
                        return lh;
                    } else if (i == 1) {
                        ListNode* it = new ListNode(1);
                        it->next = nullptr;
                        r->next = it;
                        rh = turnDown(rh);
                        return rh;
                    }
                }


            }
            return nullptr;
    }

三、牛客 链表Debug

今天刷题发现牛客Debug不能用了,原来那是会员特权,可是我已经用习惯了Debug,没有Debug我都不会探索解题方向了,于是我写了一个链表转化代码可以在本地进行Debug。

//YourClass.h

    struct ListNode {
        int val;
        struct ListNode *next;
        ListNode(int x) : val(x), next(nullptr) {}
    };
    ListNode* scanListNode(const vector<int>& vec);

//YourClass.cpp

YourClass::ListNode *YourClass::scanListNode(const vector<int> &vec)
{
    ListNode *vHead = new  ListNode(0);
    ListNode *m=vHead;

    for (const auto& element : vec) {
        ListNode *it = new  ListNode(element);
        m->next = it;
        m=m->next;
    }
    return vHead->next;
}

//main
    vector<int> myVector1 = {9,3,7};
    YourClass *yourClass= new YourClass();
    YourClass::ListNode *l = yourClass->scanListNode(myVector1);

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值