• 面试算法 牛客题目 链表相加(二)


    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.代码:

    1. /*************************************************
    2. 作者:She001
    3. 时间:2022/9/28
    4. 题目: 链表相加(二)
    5. 描输入描述:
    6. 假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。
    7. 给定两个这种链表,请生成代表两个整数相加值的结果链表。
    8. 数据范围:0 \le n,m \le 10000000≤n,m≤1000000,链表任意值 0 \le val \le 90≤val≤9
    9. 要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)
    10. ***************************************************/
    11. //算法:
    12. //1.暴力算法
    13. // 2.翻转链表算法
    14. #include<bits/stdc++.h>
    15. using namespace std;
    16. typedef struct node
    17. {
    18. int i;
    19. node *next;
    20. };
    21. void print(node * head)//打印链表
    22. {
    23. node* pp= head;//复制头节点
    24. while(pp!=NULL)//判断这个节点是否为空 链表是否结束
    25. {
    26. cout<<pp->i<<" ";
    27. pp=pp->next;//指向下一个
    28. }
    29. cout<<endl;
    30. }
    31. int lianbiao_num(node * head)//函数的作用 返回链表的个数
    32. {
    33. int i=0;
    34. node* pp=head;
    35. while(pp!=NULL)
    36. {
    37. i++;
    38. pp=pp->next;
    39. }
    40. //cout<<"链表中节点的个数: "<<i<<endl;
    41. return i;
    42. }
    43. node * reverseList(node* head)//翻转链表
    44. {
    45. if(head==NULL)
    46. {
    47. return NULL;
    48. }
    49. node * a = head;
    50. node * b = NULL;
    51. while(a!=NULL)
    52. {
    53. node * c = a->next;
    54. a->next=b;
    55. b=a;
    56. a=c;
    57. }
    58. return b;
    59. }
    60. //暴力算法
    61. //算法思想:先把数字 加到 链表最长的那个链表上 然后利用递归 进位 ,最后传递链表
    62. int digui(node * head)//递归的方法, 解决进位的问题
    63. {
    64. if(head==NULL)
    65. {
    66. return 0;
    67. }
    68. int n= head->i + digui(head->next);
    69. int a=n/10;
    70. head->i=n%10;
    71. return a;
    72. }
    73. node * fangfa_1(node * head1,node * head2)//实现的方法
    74. {
    75. if(head1==NULL)//一个链表为空 返回另外一个链表
    76. {
    77. return head2;
    78. }
    79. if(head2==NULL)
    80. {
    81. return head1;
    82. }
    83. node* k1=head1;
    84. node* k2=head2;
    85. int a1= lianbiao_num(k1);
    86. int a2= lianbiao_num(k2);
    87. if(a1>a2)//链表长度的比较
    88. {
    89. for(int i=1;i<=a1-a2;i++)//对齐链表 方便相加
    90. {
    91. k1=k1->next;
    92. }
    93. while(k1!=NULL && k2!= NULL)//对应的位数相加
    94. {
    95. k1->i=(k1->i)+ (k2->i);
    96. k1=k1->next;
    97. k2=k2->next;
    98. }
    99. digui(head1);//进位
    100. return head1;//返回链表
    101. }
    102. else
    103. {
    104. for(int i=1;i<=a2-a1;i++)//对齐链表 方便相加
    105. {
    106. k2=k2->next;
    107. }
    108. while(k1!=NULL && k2!= NULL)//对应的位数相加
    109. {
    110. k2->i=(k1->i)+ (k2->i);
    111. k1=k1->next;
    112. k2=k2->next;
    113. }
    114. digui(head2);//进位
    115. return head2;
    116. }
    117. return NULL;
    118. }
    119. //翻转链表算法
    120. /*
    121. 算法思想:
    122. 思路:
    123. 既然链表每个节点表示数字的每一位,那相加的时候自然可以按照加法法则,从后往前依次相加。
    124. 但是,链表是没有办法逆序访问的,这是我们要面对第一只拦路虎。
    125. 解决它也很简单,既然从后往前不行,那从前往后总是可行的吧,将两个链表反转一 下:
    126. */
    127. /*
    128. 1 2 3 4 5 6 7 8 9
    129. 1 2 3 4 5 6 7
    130. 1 2 4 6 9 1 3 5 6
    131. */
    132. node * fangfa_2(node * head1,node* head2)
    133. {
    134. if(head1==NULL)
    135. {
    136. return head2;
    137. }
    138. if(head2==NULL)
    139. {
    140. return head1;
    141. }
    142. //翻转两个链表
    143. head1= reverseList(head1);
    144. //print(head1);
    145. head2= reverseList(head2);
    146. //print(head2);
    147. //添加表头 之后翻转答案 就是 结尾 NULL
    148. node *res = new node;
    149. res->i=-1;
    150. node* head=res;
    151. int carry=0;//进位符号
    152. //只有两个链表不为空, 或者 进位的符号不为 0 那么创建一个新的节点,就不会停止
    153. while(head1!=NULL || head2!=NULL || carry!=0)
    154. {
    155. int value1=0;
    156. int value2=0;
    157. //链表不为空 取它的值
    158. if(head1!=NULL)
    159. {
    160. value1=head1->i;
    161. }
    162. if(head2!=NULL)
    163. {
    164. value2=head2->i;
    165. }
    166. //相加
    167. int temp = value1 + value2 +carry;
    168. carry=temp/10;
    169. temp=temp%10;
    170. //添加元素
    171. head->next= new node;
    172. head=head->next;
    173. head->i=temp;
    174. //下一个节点
    175. if(head1!=NULL)
    176. {
    177. head1=head1->next;
    178. }
    179. if(head2!=NULL)
    180. {
    181. head2=head2->next;
    182. }
    183. }
    184. head= reverseList(res->next);
    185. delete res;
    186. return head;
    187. }
    188. int main()
    189. {
    190. //建立 第一个 单链表
    191. node *a1=new node;
    192. node *a2=new node;
    193. node *a3=new node;
    194. node *a4=new node;
    195. node *a5=new node;
    196. node *a6=new node;
    197. node *a7=new node;
    198. node *a8=new node;
    199. node *a9=new node;
    200. a1->i=1;//链表节点的复制
    201. a2->i=2;
    202. a3->i=3;
    203. a4->i=4;
    204. a5->i=5;
    205. a6->i=6;
    206. a7->i=7;
    207. a8->i=8;
    208. a9->i=9;
    209. a1->next=a2;//链表的连接
    210. a2->next=a3;
    211. a3->next=a4;
    212. a4->next=a5;
    213. a5->next=a6;
    214. a6->next=a7;
    215. a7->next=a8;
    216. a8->next=a9;//a5 是 两个链表的节点
    217. a9->next=NULL;
    218. //建立 第二个 单链表
    219. node *b1=new node;
    220. node *b2=new node;
    221. node *b3=new node;
    222. node *b4=new node;
    223. node *b5=new node;
    224. node *b6=new node;
    225. node *b7=new node;
    226. b1->i=1;//链表节点的复制
    227. b2->i=2;
    228. b3->i=3;
    229. b4->i=4;
    230. b5->i=5;
    231. b6->i=6;
    232. b7->i=7;
    233. b1->next=b2;//链表的连接
    234. b2->next=b3;
    235. b3->next=b4;
    236. b4->next=b5;
    237. b5->next=b6;
    238. b6->next=b7;
    239. b7->next=NULL;
    240. node *k1 =fangfa_1(a1,b1);
    241. print(k1);
    242. //node *k =fangfa_2(a1,b1);
    243. //print(k);
    244. return 0;
    245. }


     

  • 相关阅读:
    nodejs+vue养老人员活体鉴权服务系统elementui
    WIFI6E中的MESH组网功能
    学信息系统项目管理师第4版系列08_管理科学基础
    正点原子IMX6ULL驱动开发复盘
    AI视频教程下载:ChatGPT个人生产力提升指南
    SuperMap iServer 备份恢复与迁移
    QQ plot 的解读
    ARM汇编与C言语的混合编程
    Revisiting Time Series Outlier Detection: Definitions and Benchmarks
    Devops团队
  • 原文地址:https://blog.csdn.net/she666666/article/details/127108441