描述
假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。
给定两个这种链表,请生成代表两个整数相加值的结果链表。
例如:链表 1 为 9->3->7,链表 2 为 6->3,最后生成新的结果链表为 1->0->0->0,937+63=1000。
方法一:
解题思路:
- 利用两个栈,先将每个链表各自压入栈,链表 1 为9->3->7压入s1栈就变成自顶向下7,3,9 链表 2 为 6->3压入s2栈就变成自顶向下就是3,6
- 每次从s1和s2中取出一个栈顶数字进行相加得到n,相当于低位相加,相加完的结果如果大于等于10,说明有进位,将变量ca变成1,创建一个新节点new1=[n%10],比如7+3=10,ca=1,new1=0
- 若s1或s2里有一个栈里面没有元素,就变成加0,比如9 + 0 + 1 = 10(ca=1时)
- 当创建到new2节点,就让new2指向new1
- 当最后两个栈都没元素后,判断ca是否等于1,不等于的话直接返回node,若ca=1,新建节点[1]指向node,变成新node后再返回node
缺点:空间复杂度较高,因为需要额外开辟两个栈,浪费内存。如下图所示
import java.util.Scanner;
import java.util.Stack;
class Node{
public int value;
public Node next;
public Node(int value){
this.value=value;
}
}
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
String[] n=in.nextLine().split(" ");
String[] num1=in.nextLine().split(" ");
String[] num2=in.nextLine().split(" ");
Node node1=transForNode(num1);
Node node2=transForNode(num2);
Node nodeF=addList1(node1,node2);//计算完的链表
show(nodeF);
}
//打印链表
public static void show(Node head){
while(head!=null){
System.out.print(head.value+" ");
head=head.next;
}
System.out.println();
}
//数组转链表
public static Node transForNode(String[] nums) {
Node head = new Node(Integer.parseInt(nums[0]));
Node cur = head;
for(int i = 1; i < nums.length; i++) {
cur.next = new Node(Integer.parseInt(nums[i]));
cur = cur.next;
}
return head;
}
public static Node addList1(Node head1,Node head2){
Stack<Integer> s1=new Stack<Integer>();
Stack<Integer> s2=new Stack<Integer>();
while(head1!=null){
s1.push(head1.value);
head1=head1.next;
}
while(head2!=null){
s2.push(head2.value);
head2=head2.next;
}
int ca=0;//有进位,就令ca=1,没进位 ca=0
int n1=0;//s1的栈顶值
int n2=0;//s2的栈顶值
int n=0;//ca+n1+n2的总和
Node node=null;
Node pre=null;
while(!s1.isEmpty()||!s2.isEmpty()){
n1=s1.isEmpty()?0:s1.pop();
n2=s2.isEmpty()?0:s2.pop();
n=ca+n1+n2;
pre=node;
node=new Node(n%10);//余数
node.next=pre;//第一次指向null,后面指向新节点
ca=n/10;//进位数
}
if(ca==1){//ca仍然等于1时创建节点【1】指向原本的node,变成最新的node
pre=node;
node=new Node(1);
node.next=pre;
}
return node;//新的node
}
}
方法二:
解题思路:
- 将两个链表逆序,得到了从低位到高位的数字
- 同步遍历两个逆序后的链表,相加的和生成新节点,依次相加后得到从高位到低位的新链表,同时关注每一步是否有进位,ca=1代表有进位。具体过程在方法一中体现。
- 将传入的两个链表再逆序一下,调整回来
- 返回新链表
import java.util.Scanner;
import java.util.Stack;
class Node{
public int value;
public Node next;
public Node(int value){
this.value=value;
}
}
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
String[] n=in.nextLine().split(" ");
String[] num1=in.nextLine().split(" ");
String[] num2=in.nextLine().split(" ");
Node node1=transForNode(num1);
Node node2=transForNode(num2);
//Node nodeF=addList1(node1,node2);//方法1
Node nodeF=addList2(node1,node2);//方法2
show(nodeF);
}
//打印链表
public static void show(Node head){
while(head!=null){
System.out.print(head.value+" ");
head=head.next;
}
System.out.println();
}
//数组转链表
public static Node transForNode(String[] nums) {
Node head = new Node(Integer.parseInt(nums[0]));
Node cur = head;
for(int i = 1; i < nums.length; i++) {
cur.next = new Node(Integer.parseInt(nums[i]));
cur = cur.next;
}
return head;
}
//方法1:利用两个栈进行低位相加,得出新链表然后输出,需要额外开辟栈,造成内存过大
/*public static Node addList1(Node head1,Node head2){
Stack<Integer> s1=new Stack<Integer>();
Stack<Integer> s2=new Stack<Integer>();
while(head1!=null){
s1.push(head1.value);
head1=head1.next;
}
while(head2!=null){
s2.push(head2.value);
head2=head2.next;
}
int ca=0;//有进位,就令ca=1,没进位 ca=0
int n1=0;//s1的栈顶值
int n2=0;//s2的栈顶值
int n=0;//ca+n1+n2的总和
Node node=null;
Node pre=null;
while(!s1.isEmpty()||!s2.isEmpty()){
n1=s1.isEmpty()?0:s1.pop();
n2=s2.isEmpty()?0:s2.pop();
n=ca+n1+n2;
pre=node;
node=new Node(n%10);//余数
node.next=pre;//第一次指向null,后面指向新节点
ca=n/10;//进位数
}
if(ca==1){//ca仍然等于1时创建节点【1】指向原本的node,变成最新的node
pre=node;
node=new Node(1);
node.next=pre;
}
return node;//新的node
}*/
//方法2:逆序链表进行低位相加得到从高位到低位的新链表,然后再输出,不必额外开辟栈结构
public static Node addList2(Node head1,Node head2){
head1=reverseList(head1);
head2=reverseList(head2);
int ca=0;//有进位,就令ca=1,没进位 ca=0
int n1=0;//s1的栈顶值
int n2=0;//s2的栈顶值
int n=0;//ca+n1+n2的总和
Node c1=head1;
Node c2=head2;
Node node=null;
Node pre=null;
while(c1 != null || c2 != null){
n1=c1!=null?c1.value:0;
n2=c2!=null?c2.value:0;
n=ca+n1+n2;
pre=node;
node=new Node(n%10);//余数
node.next=pre;//第一次指向null,后面指向新节点
ca=n/10;//进位数
c1=c1!=null?c1.next:null;
c2=c2!=null?c2.next:null;
}
if(ca==1){//ca仍然等于1时创建节点【1】指向原本的node,变成最新的node
pre=node;
node=new Node(1);
node.next=pre;
}
reverseList(head1);
reverseList(head2);
return node;//新的node
}
//反转链表
public static Node reverseList(Node head){
Node pre=null;
Node next=null;
while(head!=null){
next=head.next;
head.next=pre;
pre=head;
head=next;
}
return pre;
}
}