算法就是解题方案的准确而完整的描述,是一系列解决问题的清晰指令。一些大厂经常会考察面试者算法能力,观察面试者编码的熟练程度、思考的速度和深度,以此衡量面试者的能力和潜力,所以算法重要性不言而喻。想进大厂,就必须拿下算法,而算法学习,就是要不断地练习。为了帮助大家提升算法能力,我将带大家每天做一道算法题!
今天的题目是两数相加(Add Two Numbers),涉及到链表。链表是一种线性数据结构,其中的每个元素实际上是一个单独的对象,而所有对象都通过每个元素中的引用字段链接在一起。
题目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
} }
|
题解
方法一:模拟
思路及算法
由于输入的两个链表都是逆序存储数字的位数的,因此两个链表中同一位置的数字可以直接相加。
我们同时遍历两个链表,逐位计算它们的和,并与当前位置的进位值相加。具体而言,如果当前两个链表处相应位置的数字为 n1,n2,进位值为 carry,则它们的和为 n1+n2+carry;其中,答案链表处相应位置的数字为 (n1+n2+carry) mod 10,而新的进位值为 (n1+n2+carry)/10。
如果两个链表的长度不同,则可以认为长度短的链表的后面有若干个 0 。
此外,如果链表遍历结束后,有 carry>0,还需要在答案链表的后面附加一个节点,节点的值为 carry。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode head = new ListNode(); ListNode curr = head; int carry = 0, sum = 0; while (l1 != null || l2 != null) { if (l1 != null && l2 != null) { sum = l1.val + l2.val + carry; l1 = l1.next; l2 = l2.next; } else if (l1 != null) { sum = l1.val + carry; l1 = l1.next; } else if (l2 != null) { sum = l2.val + carry; l2 = l2.next; } curr.next = new ListNode(sum % 10); curr = curr.next; carry = sum / 10; } if (carry == 1) { curr.next = new ListNode(1); } return head.next; }
|
复杂度分析
时间复杂度:O(max(m,n)),其中 m 和 n 分别为两个链表的长度。我们要遍历两个链表的全部位置,而处理每个位置只需要 O(1) 的时间。
空间复杂度:O(1)。注意返回值不计入空间复杂度。
方法二:递归
直接上代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public ListNode addTwoNumbers(ListNode l1, ListNode l2) { if (l1 == null) { return l2; } if (l2 == null) { return l1; } int val = l1.val + l2.val; ListNode next = addTwoNumbers(l1.next, l2.next); if (val >= 10) { val -= 10; next = addTwoNumbers(next, new ListNode(1)); } return new ListNode(val, next); }
|
好了,今天的文章就到这里,如果觉得有所收获,请顺手点个在看或者转发吧,你们的支持是我最大的动力。