題目:數據在機器中存儲的方式,比如342,在鏈表中是逆向存儲的,所以就變成了2->4->3這樣了,同樣5->6->4就是465,給出兩個用鏈表表示的數字,求兩數字之和。要求以鏈表的方式返回,上面的例子就返回7->0->8
實現原理:
首先寫出單鏈表的結構,定義一個函數,傳入兩個鏈表。當兩個鏈表的其中一個鏈表爲空時,則將鏈表裏面存放的數據用0表示,當兩個鏈表都爲空時,說明相加已經完成,不能在繼續進行相加了。先從低位開始相加,也就是表頭的開始處開始相加。由於每位數字都應該處於0-9的範圍內,計算的時候可能出現溢出。例如5+7=12.這種情況,將當前的位的數值爲2,定義一個用於保存進位值的變量carry,計算時帶入下一次迭代,進位值必定是0,或者1。
實現代碼:
package cn.mrlij.function;
/**
* 數據在機器中存儲的方式,比如342,在鏈表中是逆向存儲的,所以就變成了2->4->3這樣了,同樣5->6->4就是465,給出兩個用鏈表
* 表示的數字,求兩數字之和。要求以鏈表的方式返回,上面的例子就返回7->0->8
*
* 遇到特殊情況,進位的 343 + 463 = 806
*/
public class NodeSum {
/**
* 將兩個鏈表的數據分別對應相加
* @param n1
* @param n2
* @return
*/
public static Node addTwoNum(Node n1, Node n2){
Node newHead = new Node(0);//定義新鏈表
Node p =n1.next, q = n2.next,curr = newHead;
int carry = 0;//用於保存進位
//當p和q的爲空時,默認鏈表的數據爲零
while (p!=null||q!=null){
int x = p ==null?0:p.data;
int y = q == null?0:q.data;
int sum = x+y+carry;//將鏈表取出的值相加並加上進位
carry = sum/10;//得到進位,用於下一次相加
curr.next = new Node(sum%10);//將餘數保存到curr下個位置中
curr = curr.next;//將當前位置的下個位置指向當前位置,目的是爲了方便鏈接下個節點
if(p != null) p = p.next;//當前節點處理完則處理下個節點
if(q != null) q = q.next;//當前節點處理完則處理下個節點
}
if(carry>0){
curr.next = new Node(carry);
}
return newHead.next;
}
public static void main(String[] args) {
NodeDemo nd1 = new NodeDemo();
//431+285 = 716
nd1.add(new Node(1));
nd1.add(new Node(3));
nd1.add(new Node(4));
NodeDemo nd2 = new NodeDemo();
nd2.add(new Node(5));
nd2.add(new Node(8));
nd2.add(new Node(2));
Node node = addTwoNum(nd1.getHead(), nd2.getHead());
while(node!=null){
System.out.println(node.data);
node = node.next;
}
}
}
class NodeDemo{
private Node head = new Node(0);
public Node getHead() {
return head;
}
public void add(Node node) {
//先找出最後的一個節點,把新加的節點放在最後一個節點的後面
Node temp = head;
while(true) {
if(temp.next == null) {
break;
}
temp = temp.next;
}
temp.next = node;
}
}
class Node{
public int data;
public Node next;
public Node(int data){
this.data = data;
}
@Override
public String toString() {
return "Node{" +
"data=" +data+"}";
}
}