算法打卡第七条 牛客BM 11 链表相加(二)

        今天是秋招预备队算法篇第七天,今天继续摆烂,只写了一道题,并且博客是第二天补上的

        问题:链表相加

        描述:

        假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。给定两个这种链表,请生成代表两个整数相加值的结果链表。

        数据范围0≤n,m≤1000000,链表任意值 0≤val≤9
        要求:空间复杂度 O(n),时间复杂度 O(n)

        解题方法:

        链表从尾部开始计算,反向遍历做运算,组成新链表,所以要想办法到达两个链表的尾部,然后再做逻辑运算

        1、栈

            1)将两个链表分别压入两个栈中,链表结点刚好反转
            2)依次从两个栈顶取出结点,进行值的相加
            3)若和不小于10,则为下一次所取的结点和进1,若小于10,则直接作为新链表结点值
            4)重复②③,直到其中一个栈为空
            5)若在链表为空前的和向前进1,则与另一个栈的元素进行运算,直到这个栈也为空,否则直接将另一个栈的元素连在新链表上

import java.util.*;
 
/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */
 
public class Solution {
    /**
     *
     * @param head1 ListNode类
     * @param head2 ListNode类
     * @return ListNode类
     */
    public ListNode addInList (ListNode head1, ListNode head2) {
        //两个链表为空
        if(head1 == null && head2 == null){
            return null;
        }
        //head1为空
        if(head1 == null && head2 != null){
            return head2;
        }
        //head2为空
        if(head1 != null && head2 == null){
            return head1;
        }
        //入栈
        Stack<ListNode> stack1 = new Stack<>();
        Stack<ListNode> stack2 = new Stack<>();
        while(head1 != null){
            stack1.push(head1);
            head1 = head1.next;
        }
        while(head2 != null){
            stack2.push(head2);
            head2 = head2.next;
        }
        //新链表表头
        ListNode head = null;
        //进位
        int carry = 0;
        //两个栈至少有一个不为空
        while(!stack1.isEmpty() || !stack2.isEmpty()){
            //进位
            int sum = carry;
            //链表结点的值
            if(!stack1.isEmpty())
                sum = sum + stack1.pop().val;
            //另一个链表结点的值
            if(!stack2.isEmpty())
                sum = sum + stack2.pop().val;
            //计算进位
            carry = sum / 10;
            //新链表结点
            ListNode tmp = new ListNode(sum % 10);
            //连接新链表
            tmp.next = head;
            //移动头节点
            head = tmp;
        }
        //如果最后结点存在进位
        if(carry > 0){
            ListNode tmp = new ListNode(carry);
            tmp.next = head;
            head = tmp;
        }
        return head;
    }
}

        时间复杂度:O(n)。取决于链表的长度。
        空间复杂度:O(n),使用了栈存储长度为n的链表

       2、反转链表法(推荐使用)

            1)任意一个链表为空,返回另一个链表就行了,因为链表为空相当于0,0加任何数为0,包括另一个加数为0的情况。
            2)相继反转两个待相加的链表
            3)设置返回链表的链表头,设置进位carry=0.
            4)从头开始遍历两个链表,直到两个链表节点都为空且carry也不为1. 每次取出不为空的链表节点值,为空就设置为0,将两个数字与carry相加,然后查看是否进位,将进位后的结果(对10取模)加入新的链表节点,连接在返回链表后面,并继续往后遍历。
            5)返回新链表。       

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */


public class Solution {
    /**
     * 
     * @param head1 ListNode类 
     * @param head2 ListNode类 
     * @return ListNode类
     */
    public ListNode addInList (ListNode head1, ListNode head2) {
        //任意一个链表为空,返回另一个
        if(head1 == null){
            return head2;
        }
        if(head2 == null){
            return head1;
        }
        //反转链表
        ListNode pHead1 = reverseList(head1);
        ListNode pHead2 = reverseList(head2);
        //按照链表做逻辑运算
        //新链表头结点
        ListNode head = null;
        //进位
        int carry = 0;
        //当两个链表还存在结点时
        while(pHead1 != null || pHead2 != null){
            //计算和
            int sum = carry;
            if(pHead1 != null){
                sum += pHead1.val;
                pHead1 = pHead1.next;
            }
            if(pHead2 != null){
                sum += pHead2.val;
                pHead2 = pHead2.next;
            }
            ListNode tmp = new ListNode(sum % 10);
            //连接链表
            tmp.next = head;
            head = tmp;
            //进位
            carry = sum / 10;
        }
        //当链表最后结点计算完成后,还存在大于0的进位,则还需为其增加一个结点
        if(carry > 0){
            ListNode tmp = new ListNode(carry);
            tmp.next = head;
            head = tmp;
        }        
        //返回新链表
        return head;
    }
    //链表反转函数
    public ListNode reverseList(ListNode head){
        ListNode pre = null;
        while(head != null){
            ListNode tmp = head.next;
            head.next = pre;
            pre = head;
            head = tmp;
        }
        return pre;
    }
}

        时间复杂度:O(n)。取决于链表的长度。
        空间复杂度:没有用到额外的空间,所以为O(1)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值