链表:两数相加

本文介绍两种链表加法算法实现方法,一种适用于从低位到高位存储的数据,另一种适用于从高位到低位存储的数据。提供了详细代码示例及解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    根据链表中数据的存储顺序,有两种情况:一是链表按从低位到高位的顺序存储数据,二是按从高位到低位的顺序存储。

    情况一:按从低位到高位的顺序存储数据

    Example

Input: (1 -> 2 -> 3) + (4 -> 5 -> 6)
Output: 5 -> 7 -> 9
Explanation: 321 + 654 = 975.

    不需要分类判断每个链表是否为空,如果为空直接加0替代。

public ListNode Discuss(ListNode l1, ListNode l2){
        ListNode result = new ListNode(0);//定义链表时,直接初始化一个值,在后面不用再分类判断链表是否为空,再返回时直接返回result.next即可
        ListNode curr = result;
        int carry = 0;
        int sum;
        while(l1 != null || l2 != null){//不需要分类判断,只要一个链表还有值就继续循环,空的加0代替
            int x = (l1 != null) ? l1.val : 0;
            int y = (l2 != null) ? l2.val : 0;
            sum = x + y + carry;
            int val = sum % 10;
            carry = sum / 10;
            ListNode newNode = new ListNode(val);
            curr.next = newNode;
            curr = curr.next;
            if(l1 != null)//如果为空,则不再往下遍历
                l1 = l1.next;
            if(l2 != null)
                l2 = l2.next;
        }
        if(carry != 0){//注意最后可能还要加进位
            ListNode tmp = new ListNode(carry);
            curr.next = tmp;
        }
        return result.next;
    }

    更简洁的解法:直接把carry也加入到while的循环条件中,后面不用再专门判断是否还有进位:

 while(l1 != null || l2 != null || carry)

    情况二:按从高位到低位的顺序存储

Input: (1 -> 2 -> 3) + (4 -> 5 -> 6)
Output: 5 -> 7 -> 9
Explanation: 123 + 456 = 579

    这种情况可以先把链表进行倒序,然后按照上面的方法来计算。也可以用其他方法计算。

    方法1:按照正常的计算思维来设计算法

    1、计算两个链表的长度

    2、对齐两个链表,如果缺位的用0补齐

    3、采用递归的方法计算结果

    4、判断首位是否为0,得到最后结果

    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode p1 = l1;
        ListNode p2 = l2;
        int n1 = getLength(l1);
        int n2 = getLength(l2);
        p1 = n1 <= n2 ? l1 : l2;    //p1为较短的数,便于对齐
        p2 = n1 <= n2 ? l2 : l1;
    		for(int i = n1; i < n2; i++) {
    			ListNode newNode = new ListNode(0);
    			newNode.next = p1;
    			p1 = newNode;
    		}
       ListNode result = add(p1, p2);
       if(result.val == 0)
    	   	return result.next;
       else
    	   	return result;
    }
    public int getLength(ListNode head) {
    		int count = 0; ListNode p = head;
    		while(p != null){
                p = p.next;
                count ++;
            }
    		return count;
    }
    public ListNode add(ListNode l1, ListNode l2) {
    		ListNode result = new ListNode(0);
    		if(l1.next == null) {    //最后一个节点
    			int num = l1.val + l2.val;
    			ListNode sum = new ListNode(num);
    			if(num > 9) {
    				result.val += 1;
    				sum.val -= 10;
    			}
    			result.next = sum;
    			return result;
    		}
    		else {
    			ListNode p = add(l1.next, l2.next);    //递归计算后面的节点
    			int num = l1.val + l2.val + p.val;
    			ListNode sum = new ListNode(num);
    			sum.next = p.next;    //注意要把本节点的计算结果和后面元素的计算结果链接起来
    			if(num > 9) {
    				result.val += 1;
    				sum.val -= 10;
    			}
    			result.next = sum;
    			return result;
    		}
    }

    方法2:使用栈,把链表的顺序再倒过来(这种方法空间复杂度应该是比较高的)

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        Stack<Integer> s1 = new Stack<Integer>();
        Stack<Integer> s2 = new Stack<Integer>();
        
        while(l1 != null) {
            s1.push(l1.val);
            l1 = l1.next;
        };
        while(l2 != null) {
            s2.push(l2.val);
            l2 = l2.next;
        }
        
        int sum = 0;
        ListNode list = new ListNode(0);
        while (!s1.empty() || !s2.empty()) {
            if (!s1.empty()) sum += s1.pop();
            if (!s2.empty()) sum += s2.pop();
            list.val = sum % 10;
            ListNode head = new ListNode(sum / 10);
            head.next = list;
            list = head;
            sum /= 10;
        }
        
        return list.val == 0 ? list.next : list;
    }
    方法3:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值