这个问题主要涉及一个链表的原地掉头问题,和链表的边界问题。
一、使用指针组实现原地掉头
在这里我抛弃了前文中使用插入方式的链表转向,转用指针组扫描的方式用原地掉头实现链表转向。
具体思路为使用三个指针扫描过所有链表,将下一个节点的指针调转,使其指向上一个节点
其中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);