目录
链表相加(一)
链表相加(二)
描述 二与一相比多了俩次反转而已
链表相加(一)
描述
给定两个非空链表逆序存储的的非负整数,每个节点只存储一位数组。
请你把两个链表相加以下相同方法返回链表,保证两个数都不会以 0 开头。
【我的解法】长到离谱
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
/**
*
* @param head1 ListNode类
* @param head2 ListNode类
* @return ListNode类
*/
ListNode* reverse(ListNode* head)
{
ListNode* pre = nullptr, *Next = nullptr;
while(head)
{
Next = head->next;
head->next = pre;
pre = head;
head = Next;
}
return pre;
}
ListNode* addInList(ListNode* l1, ListNode* l2) {
// write code here
l1 = reverse(l1);
l2 = reverse(l2);
if (l1->val == 0)
return l2;
else if (l2->val == 0)
return l1;
ListNode* newhead = new ListNode(0);
ListNode* p = newhead;
int step = 0;
while (l1 && l2) {
int num = l1->val + l2->val + step;
if (num >= 10)
step = 1;
else
step = 0;
ListNode* newnode = new ListNode(num % 10);
p->next = newnode;
p = p->next;
l1 = l1->next;
l2 = l2->next;
}
if (l1) {
p->next = l1;
while (l1) {
l1->val += step;
if (l1->val >= 10) {
step = 1;
l1->val %= 10;
} else
step = 0;
l1 = l1->next;
p = p->next;
}
} else if (l2) {
p->next = l2;
while (l2) {
l2->val += step;
if (l2->val >= 10) {
step = 1;
l2->val %= 10;
} else
step = 0;
l2 = l2->next;
p = p->next;
}
}
if (step) {
ListNode* newNode = new ListNode(step);
p->next = newNode;
}
return reverse(newhead->next);
}
};
【答案】
具体做法:
- step 1:任意一个链表为空,返回另一个链表就行了,因为链表为空相当于0,0加任何数为0,包括另一个加数为0的情况。
- step 2:相继反转两个待相加的链表,反转过程可以参考反转链表。
- step 3:设置返回链表的链表头,设置进位carry=0.
- step 4:从头开始遍历两个链表,直到两个链表节点都为空且carry也不为1. 每次取出不为空的链表节点值,为空就设置为0,将两个数字与carry相加,然后查看是否进位,将进位后的结果(对10取模)加入新的链表节点,连接在返回链表后面,并继续往后遍历。
- step 5:返回前将结果链表再反转回来。
class Solution {
public:
ListNode* ListAdd(ListNode* head1, ListNode* head2) {
ListNode* res = new ListNode(-1);
ListNode* head = res;
//进位符号
int carry = 0;
//只要某个链表还有或者进位还有
while(head1 != NULL || head2 != NULL || carry != 0){
//链表不为空则取其值
int val1 = head1 == NULL ? 0 : head1->val;
int val2 = head2 == NULL ? 0 : head2->val;
//相加
int temp = val1 + val2 + carry;
//获取进位
carry = temp / 10;
temp %= 10;
//添加元素
head->next = new ListNode(temp);
head = head->next;
//移动下一个
if(head1 != NULL)
head1 = head1->next; // 确实一个规避段错误的小技巧
if(head2 != NULL)
head2 = head2->next;
}
//结果反转回来
return ReverseList(res->next);
}
};
链表相加(二)
描述 二与一相比多了俩次反转而已
假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。
给定两个这种链表,请生成代表两个整数相加值的结果链表。
class Solution {
public:
//反转链表
ListNode* ReverseList(ListNode* pHead) {
if(pHead == NULL)
return NULL;
ListNode* cur = pHead;
ListNode* pre = NULL;
while(cur != NULL){
//断开链表,要记录后续一个
ListNode* temp = cur->next;
//当前的next指向前一个
cur->next = pre;
//前一个更新为当前
pre = cur;
//当前更新为刚刚记录的后一个
cur = temp;
}
return pre;
}
ListNode* addInList(ListNode* head1, ListNode* head2) {
//任意一个链表为空,返回另一个
if(head1 == NULL)
return head2;
if(head2 == NULL)
return head1;
//反转两个链表
head1 = ReverseList(head1);
head2 = ReverseList(head2);
//添加表头
ListNode* res = new ListNode(-1);
ListNode* head = res;
//进位符号
int carry = 0;
//只要某个链表还有或者进位还有
while(head1 != NULL || head2 != NULL || carry != 0){
//链表不为空则取其值
int val1 = head1 == NULL ? 0 : head1->val;
int val2 = head2 == NULL ? 0 : head2->val;
//相加
int temp = val1 + val2 + carry;
//获取进位
carry = temp / 10;
temp %= 10;
//添加元素
head->next = new ListNode(temp);
head = head->next;
//移动下一个
if(head1 != NULL)
head1 = head1->next;
if(head2 != NULL)
head2 = head2->next;
}
//结果反转回来
return ReverseList(res->next);
}
};