Leetcode(2) 記:這幾天內心十分焦慮,研究生的日子一天天過去,感覺毫無收穫,每天刷個題來壓壓驚. 2.Add Two Number · 錯誤示例 · 思路 寫兩個函數將一個數從List轉化為int, 相加後再從int轉化為List返回. · 偽代碼: 1.構造兩個函數分別代表: 一個數字從 ...
Leetcode(2)
記:這幾天內心十分焦慮,研究生的日子一天天過去,感覺毫無收穫,每天刷個題來壓壓驚.
2.Add Two Number
·錯誤示例
·思路
寫兩個函數將一個數從List轉化為int, 相加後再從int轉化為List返回.
·偽代碼:
1.構造兩個函數分別代表: 一個數字從int轉化為List和從List轉化為int.
2.輸入兩個數L1和L由List表示,得I1=listConvertInt(L1)和L2=listConvertInt(L2);
3.返回L3 = intConvertList(L1 + L2);
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int i = listConvertInt(l1);
int j = listConvertInt(l2);
return intConvertList(j + i);
}
public int listConvertInt(ListNode l1) {
int i = 0;
int j = 1;
ListNode temp = l1;
while (temp != null) {
i += temp.val * j;
j *= 10;
temp = temp.next;
}
return i;
}
public ListNode intConvertList(int i) {
int temp = i;
int val;
ListNode head = new ListNode(0);
ListNode curr = head;
while (temp != 0) {
val = temp % 10;
temp /= 10;
ListNode next = new ListNode(val);
curr.next = next;
curr = next;
}
if (head.next != null) {
head = head.next;
}
return head;
}
}
·結果
輸入
[9]
[1,9,9,9,9,9,9,9,9,9,9,9,9]
輸出 [2,1,9,4,3,1,6,1,3,1]
預期結果 [0,0,0,0,0,0,0,0,0,0,0,0,0,1]
報錯的原因很簡單,java的int是4個位元組也就是其表示範圍是:(-2^31,2^31-1);(-2147483648,2147483647)。該輸入相加後得到的數已經為11位。long也不行。想著可以用Java的大數或者轉化為String解決這個問題,感覺更麻煩了。只能用倆個鏈表模擬加法運算了.
·正確答案
·思路
設置一個carry代表當前位相加後的溢出進位,因為鏈表正好是反向的,剛剛好可以模擬兩數從低位相加到高位的操作過程.
·偽代碼:
1.將當前的結點初始化為返回列表的啞結點(頭部空結點)
2.將當前進位carry初始化為0
3.將p和q分別初始化為l1和l2的頭部
4.遍歷列表l1和l2直至到達它們的尾端
·將x設置為結點p的值。如果p已經到達l1的末尾,則將其值設置為0
·將y設置為結點q的值。如果q已經到達l2的末尾,則將其值設置為0
·設定sum = x + y + carry
·更新進位的值,carry = sum\10
·創建一個數值為(sum mod 10)的新結點n,並將其設置為當前結點curr的下一節點,然後將當前結點curr前進到下一節點n
·同時,將p和q前進到下一個結點
5.檢查carry = 1 是否成立,如果成立,則向返回列表追加一個含有數字1的新結點
6.返回啞節點的下一個結點
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode head = new ListNode(0);
int carry = 0;
ListNode p = l1;
ListNode q = l2;
ListNode curr = head;
while(p != null || q != null){
int x = (p != null) ? p.val : 0;
int y = (q != null) ? q.val : 0;
int sum = x + y + carry;
carry = sum / 10;//後插法
curr.next = new ListNode(sum % 10);
curr = curr.next;
if(p != null) p = p.next;
if(q != null) q = q.next;
}
if(carry == 1){
curr.next = new ListNode(1);
}
return head.next;
}
·結果
執行用時 : 10 ms, 在Add Two Numbers的Java提交中擊敗了100.00% 的用戶
記憶體消耗 : 47.1 MB, 在Add Two Numbers的Java提交中擊敗了20.73% 的用戶
小結
該題解複雜度分析
·時間複雜度:O(max(m,n)),m,n分別代表l1和l2的長度
·空間複雜度:O(max(m,x)),新列表的長度最多為max(m.n)+1
根據官方的答案我又自己看著偽代碼敲了一遍收穫很多.
- 敲代碼前最好要寫偽代碼
- 適當應用 ? 三元運算符來簡化代碼
- 參數最好別混用(其實只用head就夠了不需要curr)
總結與思考
我覺得對於我來說不宜多刷宜精刷題。
1.考慮怎樣能降低空間複雜度?
2.如果鏈表中的數字是按照順序存儲會怎樣?