原文:
You have two numbers represented by a linked list, where each node contains a single digit. The digits are stored in reverse order, such that the 1’s digit is at the head of the list. Write a function that adds the two numbers and returns the sum as a linked
list.
EXAMPLE
Input: (3 -> 1 -> 5), (5 -> 9 -> 2)
Output: 8 -> 0 -> 8
译文:
你有两个由单链表表示的数。每个结点代表其中的一位数字。数字的存储是逆序的, 也就是说个位位于链表的表头。写一函数使这两个数相加并返回结果,结果也由链表表示。
例子:(3 -> 1 -> 5), (5 -> 9 -> 2)
输入:8 -> 0 -> 8
思路:递归
1) 如果整数在链表中是以倒置方式存放的,那么容易相加
2) 如果整数在链表中是以顺序方式存放的,那么要 1先分别计算两个链表长度 2 把短的链表短的部分补零,使得两链表长度相同 3 递归相加,返回值用一个WrapperNode,不光存放相加后的节点,而且存放carry值。 所以用到方法有:length,padList,addListsHelper,insertBefore
值得主义的情况有:1.链表为空。2.有进位。3.链表长度不一样。
package LinkLists;
import CtCILibrary.LinkedListNode;
public class S2_5 {
// 当值以reverse order存放在链表时,递归
// 如: 9->9->9
// + 1
// = 0->0->0->1
public static LinkedListNode addListsReverse(LinkedListNode l1, LinkedListNode l2,
int carry) {
if (l1 == null && l2 == null && carry == 0) {
return null;
}
// 新建当前结果节点
LinkedListNode result = new LinkedListNode(carry, null, null);
int value = carry;
if (l1 != null) {
value += l1.data;
}
if (l2 != null) {
value += l2.data;
}
result.data = value % 10; // 设置当前结果节点值
// 递归
result.next = addListsReverse(l1 == null ? null : l1.next, l2 == null ? null
: l2.next, value / 10);
return result;
}
//===========================================
// 当把值以顺序存放链表:
// 如: 9->9->9
// + 1
// = 1->0->0->0
public static LinkedListNode addLists(LinkedListNode l1, LinkedListNode l2) {
int len1 = length(l1);
int len2 = length(l2);
// 给较短的链表补零
if(len1 < len2) {
l1 = padList(l1, len2-len1); // 9->9->9
} else{
l2 = padList(l2, len1-len2); // 0->0->1
}
// System.out.println("pad1: " + l1.printForward());
// System.out.println("pad2: " + l2.printForward());
WrapperNode sum = addListsHelper(l1, l2);
if(sum.carry == 0) {
return sum.node;
} else{ // 对于最后仍有进位的情况,如:999+1=1000
LinkedListNode result = insertBefore(sum.node, sum.carry);
return result;
}
}
public static int length(LinkedListNode head) {
if(head == null){
return 0;
} else{
return 1 + length(head.next);
}
}
// 递归,两个链表相加
// l1 l1.next
// 9->9->9
// 0->0->1
// ->0 head(carry:1)
// 0->0
// head(carry:1)
public static WrapperNode addListsHelper(LinkedListNode l1, LinkedListNode l2) {
if(l1 == null && l2 == null) {
WrapperNode head = new WrapperNode();
return head;
}
// 利用递归返回下一个节点之和以及carry,都封装在head里
WrapperNode head = addListsHelper(l1.next, l2.next);
int val = head.carry + l1.data + l2.data; // 计算当前节点的和
// 把当前节点插在旧的head之前,并保存新的carry值
LinkedListNode newHead = insertBefore(head.node, val%10);
return new WrapperNode(newHead, val/10); // 返回新的wrapper,包含新头结点和carry
}
// 在head节点前面补上padding个零
public static LinkedListNode padList(LinkedListNode head, int padding) {
LinkedListNode cur = head;
for(int i=0; i<padding; i++) {
LinkedListNode newHead = new LinkedListNode(0, null, null);
cur.prev = newHead;
newHead.next = cur;
cur = newHead;
}
return cur;
}
// 把新建的data节点添加到head之前,返回插入后的新建节点
public static LinkedListNode insertBefore(LinkedListNode head, int data) {
LinkedListNode node = new LinkedListNode(data, null, null);
if(head != null) {
head.prev = node;
node.next = head;
}
return node;
}
// 把整数的链表形式转化为整数
public static int linkedListToInt(LinkedListNode node) {
int value = 0;
while (node != null) {
value = value * 10 + node.data;
node = node.next;
}
return value;
}
public static class WrapperNode {
public LinkedListNode node = null;
public int carry = 0;
public WrapperNode(){}
public WrapperNode(LinkedListNode node, int carry){
this.node = node;
this.carry = carry;
}
}
public static void main(String[] args) {
LinkedListNode lA1 = new LinkedListNode(9, null, null);
LinkedListNode lA2 = new LinkedListNode(9, null, lA1);
LinkedListNode lA3 = new LinkedListNode(9, null, lA2);
LinkedListNode lB1 = new LinkedListNode(1, null, null);
// LinkedListNode lB2 = new LinkedListNode(0, null, lB1);
// LinkedListNode lB3 = new LinkedListNode(0, null, lB2);
// LinkedListNode list3 = addListsReverse(lA1, lB1, 0);
LinkedListNode list3 = addLists(lA1, lB1);
System.out.println(" " + lA1.printForward());
System.out.println("+ " + lB1.printForward());
System.out.println("= " + list3.printForward());
int l1 = linkedListToInt(lA1);
int l2 = linkedListToInt(lB1);
int l3 = linkedListToInt(list3);
System.out.print(l1 + " + " + l2 + " = " + l3 + "\n");
System.out.print(l1 + " + " + l2 + " = " + (l1 + l2));
}
}
分享到:
相关推荐
数据结构_两个链表的合并,一元多项式相加
在visual c++6.0环境中 链表 动态链表 多项式相加
应用链表结构实现了多相式的建立,相加减运算.
用两个链表组织两个一元多项式,将相加的结果保存在前一个链表中。 输入 m(项数) c1(第一项系数) e1(第一项指数) c2 e2 ....... cm(第m项系数) em(第m项指数) n(项数) c1(第一项系数) e1(第一项指数) c2 e2 ....
(1)建立两个链表A和B 链表元素个数分别为m和n个 (2)假设元素分别为 x1 x2 …xm 和 y1 y2 …yn 把它们合并成一个线性表C 使得: 当m> n时 C x1 y1 x2 y2 …xn yn … xm 当n>m时 C y1 x1 y2 x2 …ym xm ...
c++,算法链表实现一元多项式相加,通过链表实现,非常好的一个程序
两个长度不同的链表存储一些数字,将链表中对应位置的数相加并存储在新链表里
实现两个链表类的链接,实现加法“+”对链表的实现
输入两个链表并取其交集于其中之一链表中输出
分析与解法 这样的一个问题,也许我们平时很少考虑。但在一个大的系统中,如果出现两个链表相 交的情况,而且释放了其中一个链表的...的两个链表,我们希望在释放一个链表之前知道是否有其他链表跟当前这个链表相交。
实现两个链表的合并(数据结构课程设计c语言版)
将两个有序的链表合并为一个有序链表,链表的大小是可变的
何将两个有序链表并为一个有序链表。
给出两个单向链表的头指针(如图3-8 所示),比如h1、h2,判断这两个链表是否 相交。这里为了简化问题,我们假设两个链表均不带环。
利用实现的线性表,存储一元n次多项式,完成多项式的输入、显示;实现多项式的加法操作
已有a、b两个链表,每个链表中的结点包括学号、成绩。要求把两个链表合并,按学号升序排列
对于两个链表的归并,自己想了好久才做出来的,希望对初学的人有点帮助吧
该文件里面有用C语言实现两个链表之间的连接。
设ha和hb分别是指向两个带头结点的非递减...要求设计一个算法,将这两个有序链表合并成一个非递增(递减)有序的单链表。要求结果链表仍使用原来两个链表的存储空间,不另外占用其它存储空间。表中允许有重复的数据。
C++实现两个链表组合,不重新开创链表