2-10两个单链表生成相加链表

题目描述

解题方法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));
        }
        //根据sum值建表
        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 ; //当前新节点的val值
              wei = (num1+num2+wei)/10; //更新进位信息
              newnode = new Node(val);
              newnode.next = head3.next;
              head3.next = newnode;
        }
        //创建结束后如果进位信息wei=1说明最后两个节点有进位应该再头插一个节点保存最后的进位
         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 ; //当前新节点的val值
              wei = (num1+num2+wei)/10; //更新进位信息
              newnode = new Node(val);
              newnode.next = head3.next;
              head3.next = newnode;
              p1=p1.next;
              p2=p2.next;
        }
        //创建结束后如果进位信息wei=1说明最后两个节点有进位应该再头插一个节点保存最后的进位
        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;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值