两个链表生成相加链表

 

描述

假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。

给定两个这种链表,请生成代表两个整数相加值的结果链表。

例如:链表 1 为 9->3->7,链表 2 为 6->3,最后生成新的结果链表为 1->0->0->0,937+63=1000。

方法一:

解题思路:

  1. 利用两个栈,先将每个链表各自压入栈,链表 1 为9->3->7压入s1栈就变成自顶向下7,3,9  链表 2 为 6->3压入s2栈就变成自顶向下就是3,6
  2. 每次从s1和s2中取出一个栈顶数字进行相加得到n,相当于低位相加,相加完的结果如果大于等于10,说明有进位,将变量ca变成1,创建一个新节点new1=[n%10],比如7+3=10,ca=1,new1=0
  3. 若s1或s2里有一个栈里面没有元素,就变成加0,比如9 + 0 + 1 = 10(ca=1时)
  4. 当创建到new2节点,就让new2指向new1
  5. 当最后两个栈都没元素后,判断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
    }
}

 

方法二:

解题思路:

  1. 将两个链表逆序,得到了从低位到高位的数字
  2. 同步遍历两个逆序后的链表,相加的和生成新节点,依次相加后得到从高位到低位的新链表,同时关注每一步是否有进位,ca=1代表有进位。具体过程在方法一中体现。
  3. 将传入的两个链表再逆序一下,调整回来
  4. 返回新链表
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;
    }
}

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值