两个长整数的相加
1.題目:兩個非負整數以逆序形式存儲在兩個鏈表,計算他們的和并同樣以逆序形式存進鏈表并返回。
我一開始的思路是把這兩條鏈的數按位數乘10完整提出來,然后相加,再依次取位數對應數字存進鏈里,返回。
直到他給了我這么一個測試數據,我才明白它用鏈表傳參的目的。
然后我搜了一下long long的取值范圍:
-9223372036854775808-9223372036854775807
(即-2^63 - 2^63-1)
以及unsigned long: 0-1844674407370955161
(即0 - 2^64-1)
而這個測試數據起碼有30位數!
所以完整提出來相加是不可能的了。
然后到第二個思路:
兩個指針同時在對應的相同位置遍歷兩條鏈list1和list2,把當前遍歷到的數拿出來相加,>=10則拋出進位數cnum=1,結果放到新增空間并尾插到新鏈,遍歷繼續。
這只是正常的情況,那么特殊的情況還有什么呢?
( [ ]內代表數字在鏈表里的順序)
(6000+300)
(99+9999=10098)
(99+21942=22041)
[5]+[5](5+5=10)
**對于一長一短的情況,我的思路是:
因為遍歷條件是p和q同時不為NULL,此時的遍歷已經斷掉,但仍有p!=NULL或者q!=NULL。
(下面以p!=NULL為例子)
先定義新指針k,記錄此時p的位置。
一.若此時進位數cnum為0:
將k直接連接到returnlist的尾端。
二.若此時進位數cnum為1:
則p繼續遍歷list剩下部分,每遍歷一次拋出cnum的值,直到cnum等于0,遍歷停止。
在此條件下(cnum為1),若遍歷在最后一個數前停止,將k連接到returnlist的尾端;若在最后一個數的位置停止,則新增空間將其值設為1,連接到list1尾部,再將k連接到returnlist的尾端。
**同長同短,遍歷最后一組數據進位1:
直接新增空間設置其值為1,連接到新鏈表尾部。
下面貼代碼:
思路1(局限于長整型數據類型范圍內):
思路一寫了好久也想貼一下,原諒我的菜 ╮(╯﹏╰)╭
思路二(正確解法):
/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/class Solution { public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {ListNode* answer=new ListNode, * p = l1, * q = l2,*k=NULL,*o=NULL;answer->next = NULL;ListNode *New, * flag=answer;int ans = 0,judge=0;while (p != NULL && q != NULL) { /*從鏈頭到尾 對l1和l2每個對應節點做加法*/if (judge==1) { /*如果上兩個數有進位,則加上1*/if ((p->val+q->val+judge)>=10) {ans = (p->val + q->val+judge) % 10;judge= 1;}if ((p->val + q->val+judge) < 10) {ans = p->val + q->val+judge;judge = 0;}}else {if ((p->val + q->val) >= 10) {ans = (p->val + q->val) % 10;judge = 1;}if ((p->val + q->val) < 10) {ans = p->val + q->val;judge = 0;}}New = new ListNode;New->val = ans;New->next = flag->next; /*尾插法,flag->next永遠是NULL*/flag->next = New;flag = flag->next;p = p->next; q = q->next;/*p,q遍歷*/}if (p == NULL && q == NULL&&judge==1) {New = new ListNode;New->val = 1;New->next = NULL;flag->next = New;}if (p == NULL&&q!=NULL) { /*一長一短,q還沒斷*/k = q;if (judge == 0)flag->next = k;if (judge == 1) {while (q != NULL && judge == 1) {if ((q->val + judge) >= 10) {q->val = (q->val + judge) % 10;judge = 1;}else {q->val = q->val + judge;judge = 0;}o = q;q = q->next;}if (q == NULL && judge == 1) {New = new ListNode;New->val = 1;New->next = NULL;o->next = New;}flag->next = k;}}if (q == NULL && p != NULL) {/*一長一短,p還沒斷*/k = p;if (judge == 0)flag->next = k;if (judge == 1) {while (p != NULL && judge == 1) {if ((p->val + judge) >= 10) {p->val = (p->val + judge) % 10;judge = 1;}else {p->val = p->val + judge;judge = 0;}o = p;p = p->next;}if (p == NULL && judge == 1) {New = new ListNode;New->val = 1;New->next = NULL;o->next = New;}flag->next = k;}}answer = answer->next;/*去頭(我個人認為去不去都可以)*/return answer;} };小結:
這個題目的思路對的話,再把每種情況想清楚就OK,運用一些簡單的if和else語句,還有單鏈表的尾插法與頭插法。
網上有更優的解法,輕噴。
總結
- 上一篇: 手机怎么还花呗的钱
- 下一篇: 回文数、罗马数转整数、整数反转