题目:数据在机器中存储的方式,比如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+"}";
}
}