题目描述
解题方法1
第一时间想到的方法是,我们可以把两个链表转化成两个整数,然后求和,再将求和后的整数转化为求和链表。 把链表转化为整数,我们可以先求链表表长,然后给每个节点值乘上相应的幂方,将各节点依次求和。 对整数转化为链表,我们可以使用头插法,依次对10取余将结果进行插入。 代码如下:
public class Test {
public static void main ( String[ ] args) throws Exception {
int [ ] arr1 = { 0 , 6 , 6 , 6 } ;
int [ ] arr2 = { 2 , 3 , 4 } ;
Node head1 = create ( arr1) ;
Node head2 = create ( arr2) ;
Node head3 = sum ( head1, head2) ;
for ( Node p= head3. next; p!= null; p= p. next) {
System. out. println ( p. val) ;
}
}
public static Node sum ( Node head1, Node head2) {
int len1= 0 ;
int len2= 0 ;
for ( Node p= head1. next; p!= null; p= p. next) {
len1++ ;
}
for ( Node p= head2. next; p!= null; p= p. next) {
len2++ ;
}
int num1 = 0 ;
int num2 = 0 ;
for ( Node p= head1. next; p!= null; p= p. next) {
len1-- ;
num1 = ( int ) ( num1 + p. val* Math. pow ( 10 , len1) ) ;
}
for ( Node p= head2. next; p!= null; p= p. next) {
len2-- ;
num2 = ( int ) ( num2 + p. val* Math. pow ( 10 , len2) ) ;
}
int sum = num1 + num2;
Node head3 = new Node ( 0 ) ;
Node newnode = null;
while ( sum!= 0 ) {
newnode = new Node ( sum% 10 ) ;
newnode. next = head3. next;
head3. next = newnode;
sum = sum/ 10 ;
}
return head3;
}
public static Node create ( int [ ] arr) {
Node head = new Node ( 0 ) ;
Node newnode = null;
Node lastnode = head;
for ( int a: arr) {
newnode = new Node ( a) ;
newnode. next = lastnode. next;
lastnode. next = newnode;
lastnode = newnode;
}
return head;
}
}
class Node {
int val;
Node next;
Node ( int val) {
this . val = val;
}
}
此种方法虽然可以完成要求,但是可能会有溢出的问题。如果链表长度非常长,那么int变量可能存储不了这么大的值。
解题方法2
我们可以使用栈来进行优化,首先申请两个栈,将两个链表从头到尾依次入栈。 然后再依次出栈求和将每次求和结果作为新链表的尾节点进行存储,需要注意的是如果求和之后有进位的情况发生要将进位结果保存起来供下一次求和使用。 比如 7 + 8 = 15。那么当前节点只保存5,并将进位信息1保存到一个变量中等待下次求和使用。
public class Test {
public static void main ( String[ ] args) throws Exception {
int [ ] arr1 = { 6 , 6 , 6 } ;
int [ ] arr2 = { 3 , 3 , 4 } ;
Node head1 = create ( arr1) ;
Node head2 = create ( arr2) ;
Node head3 = sum ( head1, head2) ;
for ( Node p= head3. next; p!= null; p= p. next) {
System. out. println ( p. val) ;
}
}
public static Node sum ( Node head1, Node head2) {
Stack< Integer> s1 = new Stack < > ( ) ;
Stack< Integer> s2 = new Stack < > ( ) ;
for ( Node p= head1. next; p!= null; p= p. next) {
s1. push ( p. val) ;
}
for ( Node p= head2. next; p!= null; p= p. next) {
s2. push ( p. val) ;
}
int wei = 0 ;
Node head3 = new Node ( 0 ) ;
Node newnode = null;
while ( ! s1. empty ( ) || ! s2. empty ( ) ) {
int num1 = s1. empty ( ) ? 0 : s1. pop ( ) ;
int num2 = s2. empty ( ) ? 0 : s2. pop ( ) ;
int val = ( num1+ num2+ wei) % 10 ;
wei = ( num1+ num2+ wei) / 10 ;
newnode = new Node ( val) ;
newnode. next = head3. next;
head3. next = newnode;
}
if ( wei== 1 ) {
newnode = new Node ( wei) ;
newnode. next = head3. next;
head3. next = newnode;
}
return head3;
}
public static Node create ( int [ ] arr) {
Node head = new Node ( 0 ) ;
Node newnode = null;
Node lastnode = head;
for ( int a: arr) {
newnode = new Node ( a) ;
newnode. next = lastnode. next;
lastnode. next = newnode;
lastnode = newnode;
}
return head;
}
}
class Node {
int val;
Node next;
Node ( int val) {
this . val = val;
}
}
解题方法3
使用栈结构的空间复杂度为n。我们可以对链表进行逆置,创建新链表后再将原来的链表还原,这样就不会使用到额外存储结构。 新表的建立过程与解法2类似,只不过把栈的遍历换成了逆置链表的遍历。
public class Test {
public static void main ( String[ ] args) throws Exception {
int [ ] arr1 = { 5 , 6 , 6 } ;
int [ ] arr2 = { 3 , 3 , 4 } ;
Node head1 = create ( arr1) ;
Node head2 = create ( arr2) ;
Node head3 = sum ( head1, head2) ;
for ( Node p= head3. next; p!= null; p= p. next) {
System. out. println ( p. val) ;
}
}
public static Node sum ( Node head1, Node head2) {
reserve ( head1) ;
reserve ( head2) ;
int wei = 0 ;
Node head3 = new Node ( 0 ) ;
Node newnode = null;
Node p1 = head1. next;
Node p2 = head2. next;
while ( p1!= null || p2!= null) {
int num1 = p1== null? 0 : p1. val;
int num2 = p2== null? 0 : p2. val;
int val = ( num1+ num2+ wei) % 10 ;
wei = ( num1+ num2+ wei) / 10 ;
newnode = new Node ( val) ;
newnode. next = head3. next;
head3. next = newnode;
p1= p1. next;
p2= p2. next;
}
if ( wei== 1 ) {
newnode = new Node ( wei) ;
newnode. next = head3. next;
head3. next = newnode;
}
reserve ( head1) ;
reserve ( head2) ;
return head3;
}
public static void reserve ( Node head) {
Node p = head. next;
head. next = null;
while ( p!= null) {
Node temp = p. next;
p. next = head. next;
head. next = p;
p = temp;
}
}
public static Node create ( int [ ] arr) {
Node head = new Node ( 0 ) ;
Node newnode = null;
Node lastnode = head;
for ( int a: arr) {
newnode = new Node ( a) ;
newnode. next = lastnode. next;
lastnode. next = newnode;
lastnode = newnode;
}
return head;
}
}
class Node {
int val;
Node next;
Node ( int val) {
this . val = val;
}
}