1. 题目: 链表相加(二)
输入描述:
假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。
给定两个这种链表,请生成代表两个整数相加值的结果链表。
数据范围:0 \le n,m \le 10000000≤n,m≤1000000,链表任意值 0 \le val \le 90≤val≤9
要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)

2.算法:
1.暴力算法
2.翻转链表算法
3.算法思想:
暴力算法
//算法思想:先把数字 加到 链表最长的那个链表上 然后利用递归 进位 ,最后传递链表
翻转链表算法
算法思想:
思路:既然链表每个节点表示数字的每一位,那相加的时候自然可以按照加法法则,从后往前依次相加。
但是,链表是没有办法逆序访问的,这是我们要面对第一只拦路虎。
解决它也很简单,既然从后往前不行,那从前往后总是可行的吧,将两个链表反转一 下:
4.代码:
-
- /*************************************************
- 作者:She001
- 时间:2022/9/28
- 题目: 链表相加(二)
- 描输入描述:
- 假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。
- 给定两个这种链表,请生成代表两个整数相加值的结果链表。
- 数据范围:0 \le n,m \le 10000000≤n,m≤1000000,链表任意值 0 \le val \le 90≤val≤9
- 要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)
-
-
-
- ***************************************************/
- //算法:
- //1.暴力算法
- // 2.翻转链表算法
-
- #include<bits/stdc++.h>
- using namespace std;
- typedef struct node
- {
- int i;
- node *next;
- };
-
-
- void print(node * head)//打印链表
- {
- node* pp= head;//复制头节点
- while(pp!=NULL)//判断这个节点是否为空 链表是否结束
- {
- cout<<pp->i<<" ";
- pp=pp->next;//指向下一个
- }
- cout<<endl;
-
- }
-
-
-
- int lianbiao_num(node * head)//函数的作用 返回链表的个数
- {
- int i=0;
- node* pp=head;
- while(pp!=NULL)
- {
- i++;
- pp=pp->next;
- }
- //cout<<"链表中节点的个数: "<<i<<endl;
- return i;
- }
-
- node * reverseList(node* head)//翻转链表
- {
- if(head==NULL)
- {
- return NULL;
- }
- node * a = head;
- node * b = NULL;
- while(a!=NULL)
- {
- node * c = a->next;
- a->next=b;
- b=a;
- a=c;
- }
- return b;
- }
-
-
-
-
- //暴力算法
- //算法思想:先把数字 加到 链表最长的那个链表上 然后利用递归 进位 ,最后传递链表
-
- int digui(node * head)//递归的方法, 解决进位的问题
- {
- if(head==NULL)
- {
- return 0;
- }
- int n= head->i + digui(head->next);
- int a=n/10;
- head->i=n%10;
- return a;
- }
-
-
- node * fangfa_1(node * head1,node * head2)//实现的方法
- {
- if(head1==NULL)//一个链表为空 返回另外一个链表
- {
- return head2;
- }
- if(head2==NULL)
- {
- return head1;
- }
- node* k1=head1;
- node* k2=head2;
- int a1= lianbiao_num(k1);
- int a2= lianbiao_num(k2);
-
- if(a1>a2)//链表长度的比较
- {
- for(int i=1;i<=a1-a2;i++)//对齐链表 方便相加
- {
- k1=k1->next;
- }
- while(k1!=NULL && k2!= NULL)//对应的位数相加
- {
- k1->i=(k1->i)+ (k2->i);
- k1=k1->next;
- k2=k2->next;
- }
- digui(head1);//进位
- return head1;//返回链表
-
- }
- else
- {
- for(int i=1;i<=a2-a1;i++)//对齐链表 方便相加
- {
- k2=k2->next;
- }
- while(k1!=NULL && k2!= NULL)//对应的位数相加
- {
- k2->i=(k1->i)+ (k2->i);
- k1=k1->next;
- k2=k2->next;
- }
-
- digui(head2);//进位
- return head2;
- }
-
- return NULL;
- }
-
- //翻转链表算法
- /*
- 算法思想:
- 思路:
-
- 既然链表每个节点表示数字的每一位,那相加的时候自然可以按照加法法则,从后往前依次相加。
- 但是,链表是没有办法逆序访问的,这是我们要面对第一只拦路虎。
- 解决它也很简单,既然从后往前不行,那从前往后总是可行的吧,将两个链表反转一 下:
- */
- /*
- 1 2 3 4 5 6 7 8 9
- 1 2 3 4 5 6 7
- 1 2 4 6 9 1 3 5 6
-
-
- */
-
- node * fangfa_2(node * head1,node* head2)
- {
- if(head1==NULL)
- {
- return head2;
- }
- if(head2==NULL)
- {
- return head1;
- }
-
- //翻转两个链表
- head1= reverseList(head1);
- //print(head1);
- head2= reverseList(head2);
- //print(head2);
- //添加表头 之后翻转答案 就是 结尾 NULL
- node *res = new node;
- res->i=-1;
- node* head=res;
-
- int carry=0;//进位符号
- //只有两个链表不为空, 或者 进位的符号不为 0 那么创建一个新的节点,就不会停止
- while(head1!=NULL || head2!=NULL || carry!=0)
- {
- int value1=0;
- int value2=0;
- //链表不为空 取它的值
- if(head1!=NULL)
- {
- value1=head1->i;
- }
- if(head2!=NULL)
- {
- value2=head2->i;
- }
- //相加
- int temp = value1 + value2 +carry;
- carry=temp/10;
- temp=temp%10;
- //添加元素
-
- head->next= new node;
- head=head->next;
- head->i=temp;
- //下一个节点
- if(head1!=NULL)
- {
- head1=head1->next;
- }
- if(head2!=NULL)
- {
- head2=head2->next;
- }
- }
- head= reverseList(res->next);
- delete res;
- return head;
- }
-
-
-
-
- int main()
- {
-
-
- //建立 第一个 单链表
- node *a1=new node;
- node *a2=new node;
- node *a3=new node;
- node *a4=new node;
- node *a5=new node;
- node *a6=new node;
- node *a7=new node;
- node *a8=new node;
- node *a9=new node;
-
- a1->i=1;//链表节点的复制
- a2->i=2;
- a3->i=3;
- a4->i=4;
- a5->i=5;
- a6->i=6;
- a7->i=7;
- a8->i=8;
- a9->i=9;
-
-
- a1->next=a2;//链表的连接
- a2->next=a3;
- a3->next=a4;
- a4->next=a5;
- a5->next=a6;
- a6->next=a7;
- a7->next=a8;
- a8->next=a9;//a5 是 两个链表的节点
- a9->next=NULL;
-
-
-
- //建立 第二个 单链表
- node *b1=new node;
- node *b2=new node;
- node *b3=new node;
- node *b4=new node;
- node *b5=new node;
- node *b6=new node;
- node *b7=new node;
-
-
- b1->i=1;//链表节点的复制
- b2->i=2;
- b3->i=3;
- b4->i=4;
- b5->i=5;
- b6->i=6;
- b7->i=7;
-
-
-
- b1->next=b2;//链表的连接
- b2->next=b3;
- b3->next=b4;
- b4->next=b5;
- b5->next=b6;
- b6->next=b7;
- b7->next=NULL;
-
- node *k1 =fangfa_1(a1,b1);
- print(k1);
-
- //node *k =fangfa_2(a1,b1);
- //print(k);
-
-
-
- return 0;
- }