写在前面:
1,操作一个目标链表的时候一定一定一定一定一定要用一个指针来代替本身链表头指针!!!不可以直接操作头指针!!
(以前一直以为使用另一个指针只是是为了方便操作,其实不这样的话一直将出错)
2,多使用三目判断符可以很好的简化代码 carry=sum>=10?true:false;
3,链表构建中可以使用c++特有语法:构造函数 来构建(使用初始化列表的话会更方便哦)
4,还是犯过的错误总结:要么完全按自己的思路来,要么完全按别人的思路来。把一个完整的断章取义,自我发挥是会浪费很多时间的
题目描述:
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的
每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
很丑的代码 - _ -
解题思路:
创建一个新的链表,考虑位数相同两位数相加和位数不同的两位数相加的情况。并在其中添加进位判断
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int more = 0, add = 0;
int num1 = 0; int num2 = 0;
while (l1 != NULL) { l1 = l1->next; num1++; }
while (l2 != NULL) { l2 = l2->next; num2++; }
ListNode* l = new ListNode(0);
ListNode* l3 = l;
if (num1 == num2) { // 针对同位数相加的情况
while (l1 != NULL && l2 != NULL) {
add = l1->val + l2->val;
if (add >= 10) {
more++;
l3->val = add - 10;
if (l1->next == NULL && l2->next == NULL) { // 针对最后一位(即数字最高位)进位的情况
l3 = l3->next = new ListNode(0);
l3->val == 1;
}
else l3 = l3->next = new ListNode(0);
}
else {
l3->val = add;
l3 = l3->next = new ListNode(0);
}
l1 = l1->next; l2 = l2->next;
more = 0;
}
}
if (num1 != num2) {
while (l1 != NULL || l2 != NULL) {
add = l1->val + l2->val;
if (add >= 10) {
more++;
l3->val = add - 10;
l3 = l3->next = new ListNode(0);
}
else {
l3->val = add + more;
l3 = l3->next = new ListNode(0);
}
// 处理一个链表到底,另一个链表没有到底的情况
if (l1 == NULL || l2 == NULL) {
if (l1 == NULL) { l2 = l2->next; l3->val = l2->val + more; l3 = l3->next = new ListNode(0); }
if (l2 == NULL) { l1 = l1->next; l3->val = l1->val + more; l3 = l3->next = new ListNode(0); }
}
else { l1 = l1->next; l2 = l2->next; };
more = 0;
}
}
return l3;
}
};
代码敢帅一点吗?
解题思路:
将两个数转换成同位数(即位数少的数补零填充位数),之后按同位数相加操作
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int len1=1;//记录l1的长度
int len2=1;//记录l2的长度
ListNode* p=l1;
ListNode* q=l2;
while(p->next!=NULL)//获取l1的长度
{
len1++;
p=p->next;
}
while(q->next!=NULL)//获取l2的长度
{
len2++;
q=q->next;
}
if(len1>len2)//l1较长,在l2末尾补零
{
for(int i=1;i<=len1-len2;i++)
{
q->next=new ListNode(0);
q=q->next;
}
}
else//l2较长,在l1末尾补零
{
for(int i=1;i<=len2-len1;i++)
{
p->next=new ListNode(0);
p=p->next;
}
}
p=l1;
q=l2;
bool count=false;//记录进位
ListNode* l3=new ListNode(-1);//存放结果的链表
ListNode* w=l3;//l3的移动指针
int i=0;//记录相加结果
while(p!=NULL&&q!=NULL)
{
i=count+p->val+q->val;
w->next=new ListNode(i%10);
count=i>=10?true:false;
w=w->next;
p=p->next;
q=q->next;
}
if(count)//若最后还有进位
{
w->next=new ListNode(1);
w=w->next;
}
return l3->next;
}
};
还能更帅一点吗?!
解题思路:
优化上面的代码,既然位数少的数字位数不足,那干脆连0都不补上去了,直接不加它不就好
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* head=new ListNode(-1);//存放结果的链表
ListNode* h=head;//移动指针
int sum=0;//每个位的加和结果
bool carry=false;//进位标志
while(l1!=NULL||l2!=NULL)
{
sum=0;
if(l1!=NULL)
{
sum+=l1->val;
l1=l1->next;
}
if(l2!=NULL)
{
sum+=l2->val;
l2=l2->next;
}
if(carry)
sum++;
h->next=new ListNode(sum%10);
h=h->next;
carry=sum>=10?true:false;
}
if(carry)
{
h->next=new ListNode(1);
}
return head->next;
}
};