題目:給出兩個 非空 的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式存儲的,并且它們的每個節點只能存儲 一位 數字。
如果,我們將這兩個數相加起來,則會返回一個新的鏈表來表示它們的和。
您可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。
示例:
輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 0 -> 8
原因:342 + 465 = 807
/**
* 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) {
}
題目主要考察對鏈表結構的掌握程度,鏈表中數據初始化、取值、循環等知識。
首先明白鏈表是什么樣的數據結構:鏈表通常由一連串節點組成,每個節點包含任意的實例數據(data fields)和一或兩個用來指向上一個/或下一個節點的位置的鏈接("links")
鏈表(Linked list)是一種常見的基礎數據結構,是一種線性表,但是并不會按線性的順序存儲數據,而是在每一個節點里存到下一個節點的指針(Pointer)。
使用鏈表結構可以克服數組鏈表需要預先知道數據大小的缺點,鏈表結構可以充分利用計算機內存空間,實現靈活的內存動態管理。但是鏈表失去了數組隨機讀取的優點,同時鏈表由于增加了結點的指針域,空間開銷比較大。
這里主要說明單向鏈表,單鏈表是鏈表中結構最簡單的。一個單鏈表的節點(Node)分為兩個部分,第一個部分(data)保存或者顯示關于節點的信息,另一個部分存儲下一個節點的地址。最后一個節點存儲地址的部分指向空值。
單向鏈表只可向一個方向遍歷,一般查找一個節點的時候需要從第一個節點開始每次訪問下一個節點,一直訪問到需要的位置。而插入一個節點,對于單向鏈表,我們只提供在鏈表頭插入,只需要將當前插入的節點設置為頭節點,next 指向原頭節點即可。刪除一個節點,我們將該節點的上一個節點的 next 指向該節點的下一個節點。
解答代碼如下
/**
* 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) {
ListNode resultListNode = new ListNode(0);
ListNode current = resultListNode;
int carry = 0;
while(l1 !=null || l2 !=null){
int sum = carry;
if(l1!=null){
sum += l1.val;
l1 = l1.next;
}
if(l2!=null){
sum += l2.val;
l2 = l2.next;
}
int val = sum < 10?sum:sum - 10;
carry = sum < 10 ?0:1;
current.next = new ListNode(val);
current = current.next;
}
if(carry == 1){
current.next = new ListNode(1);
}
return resultListNode.next;
}
}
方法里前兩行代碼是初始化一個鏈表和它的頭結點,然后使用 while 方法循環判斷每個鏈表是否為空,不為空就添加到 sum 里,每次取和之后判斷和是否大于 10,如果大于 10 則把 carry 設為 1 ,否則設為 0 ,因為大于 10 的時候會有進位,所以設為 1 ,val 的值也是這個道理,小于 10 就是當前值,大于 10 則是減去 10 后的值。 然后把臨時的鏈表 current 的 next 節點設為值為當前之和的節點,然后把 current 指針指向這個 next 節點。
多次循環到 l1 和 l2 都為空的時候,停止循環,此時在判斷一下 carry 是否等于 1 ,如果等于則是最后一次求和運算結果大于 10 ,所以還要把 current 鏈表添加一個 next 節點,并且節點對應的值就是 1。
最后返回這個初始定義的鏈表的 resultListNode.next 節點,因為起始位置節點值是初始化時設置的 0,所以要從 next 節點開始返回。
這里只總結了單向鏈表求和的算法,其他插入、刪除、求固定位置的節點等題目和雙向鏈表等問題下次再詳細介紹。