Problem 02. add-two-numbers

版权声明:个人水平有限,表述不当或疏漏之处欢迎读者提问交流,共同进步! 作者:J__Max 非商业转载请注明出处,商业转载请联系作者获得授权。 https://blog.csdn.net/J__Max/article/details/84535273

Problem 02. add-two-numbers

题目描述

  • 给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按逆序的方式存储的,并且它们的每一个节点只能存储一位数字。

  • 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

  • 可以假设除了0之外,这两个数都不会以0开头。

  • 示例:

    输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
    输出:7 -> 0 -> 8
    原因:342 + 465 = 807

解题思路

  • 看完题目,最初的想法就是先把链表中的数据取出来,分别转换成对应整数,将两个整数相加后再转换到链表中。写完代码后运行了一下,居然是错的???才发现链表中的整数是逆序存储的(审题!审题!)。逆序就逆序,那我就先把两个整数翻转一下,相加后再翻转,然后放进链表里不就行了?实现是实现了,不过不知道为啥一直有bug,可是我觉得思路没错啊。。。(后面有时间再来研究一下到底哪里有问题。。)

  • 感觉上面的思路太繁琐,实现起来也麻烦。还是直接在两个链表上进行加法操作吧(这应该是这道题目的初衷,因为它在链表中逆序存储,两个链表头就是对齐的,就像我们列竖式计算时从个位开始对齐)。那么我们就从链表l1和l2的表头开始进行加法运算,将对应位置的两个数字进行加和,然后判断是否有进位的情况。设置一个 carry 来存储进位的情况,假设某两位数字的和为 sum ,那么 carry = sum / 10 ,且本位的和应该为 sum / 10 。以此进行迭代,直至两个链表都遍历完成,要注意的是,循环完成之后还要判断一次 carry 是否还有进位。代码实现如下:

public class ListNode {
	int val;
	ListNode next;
	ListNode(int x) { val = x; }
}

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
	ListNode resultHead = new ListNode(0);
	ListNode p1 = l1, p2 = l2, current = resultHead;
	int carry = 0;
	while(p1 != null || p2 != null) {
		int a = p1 != null ? p1.val : 0;
		int b = p2 != null ? p2.val : 0;
		int sum = a + b + carry;
		carry = sum / 10;
		current.next = new ListNode(sum % 10);
		current = current.next;
		if(p1 != null) {
			p1 = p1.next;
		}
		if(p2 != null) {
			p2 = p2.next;
		}
	}
	if(carry > 0) {
		current.next = new ListNode(carry);
	}
	return resultHead.next;
}
  • 由于创建了一个新的链表,而这个新链表最后的长度为 max( len(l1), len(l2) ) + 1 ,也就是说空间复杂度为 O(max( len(l1), len(l2) ))。

  • 循环的执行次数为 max( len(l1), len(l2) ) ,所以最后的时间复杂度即为 O(max( len(l1), len(l2) )) 。

猜你喜欢

转载自blog.csdn.net/J__Max/article/details/84535273