剑指 Offer II 025. 链表中的两数相加(445. 两数相加 II【进阶版本】 && 2. 两数相加)
题目:
思路:
【1】剑指 Offer II 025. 链表中的两数相加(445. 两数相加 II【进阶版本】)
【1.1】链表相加,反转链表之后再相加其实是最为靠谱的
【1.2】基于进阶说不给反转,那么要么采用递归,从底层往上走。(要么就是全部取出值来形成字符串相加)
【2】2. 两数相加
代码展示:
【1】剑指 Offer II 025. 链表中的两数相加(445. 两数相加 II【进阶版本】)
基于反转链表的方式:
//时间1 ms击败100% //内存41.3 MB击败85.6% class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { if (l1 == null) return l2; if (l2 == null) return l1; ListNode tem1 = l1, tem2 = l2; int index1 = 0, index2 = 0; while (tem1 != null || tem2 != null){ if (tem1 != null) { tem1 = tem1.next; index1++; } if (tem2 != null){ tem2 = tem2.next; index2++; } } ListNode res = addTwoIndexNumbers(l1,index1,l2,index2); if (res.val >= 10) { ListNode ans = new ListNode(res.val / 10); res.val = res.val % 10; ans.next = res; res = ans; } return res; } public ListNode addTwoIndexNumbers(ListNode l1, int index1, ListNode l2, int index2) { if (index1 == 1 && index2 == 1) return new ListNode(l1.val + l2.val); int sum = 0 , val1 = 0, val2 = 0; ListNode next, res; if (index1 > index2) { next = addTwoIndexNumbers(l1.next,index1 - 1,l2,index2); val1 = l1.val; }else if (index1 < index2){ next = addTwoIndexNumbers(l1, index1,l2.next,index2 - 1); val2 = l2.val; }else{ next = addTwoIndexNumbers(l1.next,index1 - 1,l2.next,index2 - 1); val1 = l1.val; val2 = l2.val; } if (next.val >= 10){ sum = next.val / 10; next.val = next.val % 10; } res = new ListNode(val1 + val2 + sum); res.next = next; return res; } }
基于字符串相加的方式:
//时间2 ms击败68.99% //内存41.6 MB击败39.48% class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { if (l1 == null) return l2; if (l2 == null) return l1; ListNode tem1 = l1, tem2 = l2; StringBuffer buf1 = new StringBuffer(); StringBuffer buf2 = new StringBuffer(); while (tem1 != null || tem2 != null){ if (tem1 != null) { buf1.append(tem1.val); tem1 = tem1.next; } if (tem2 != null){ buf2.append(tem2.val); tem2 = tem2.next; } } int size1 = buf1.length(), size2 = buf2.length(); ListNode res = null; int diff = 0; while (size1 > 0 || size2 > 0){ int val1 = 0 , val2 = 0; if (size1 > 0) val1 = buf1.charAt(--size1) - '0'; if (size2 > 0) val2 = buf2.charAt(--size2) - '0'; int sum = val1 + val2 + diff; //差值用了就要清除 diff = 0; if (sum > 9) { diff = sum / 10; sum = sum % 10; } ListNode head = new ListNode(sum); head.next = res; res = head; } //如果最后还存在,证明是要增加一个头部节点的 if (diff != 0) { ListNode ans = new ListNode(diff); ans.next = res; res = ans; } return res; } }
基于递归的方式相加:
//时间1 ms击败100% //内存41.1 MB击败97.19% /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { if (l1 == null) return l2; if (l2 == null) return l1; ListNode tem1 = l1, tem2 = l2; int index1 = 0, index2 = 0; while (tem1 != null || tem2 != null){ if (tem1 != null) { tem1 = tem1.next; index1++; } if (tem2 != null){ tem2 = tem2.next; index2++; } } ListNode res = addTwoIndexNumbers(l1,index1,l2,index2); if (res.val >= 10) { ListNode ans = new ListNode(res.val / 10); res.val = res.val % 10; ans.next = res; res = ans; } return res; } public ListNode addTwoIndexNumbers(ListNode l1, int index1, ListNode l2, int index2) { if (index1 == 1 && index2 == 1) return new ListNode(l1.val + l2.val); int sum = 0 , val1 = 0, val2 = 0; ListNode next, res; if (index1 > index2) { next = addTwoIndexNumbers(l1.next,index1 - 1,l2,index2); val1 = l1.val; }else if (index1 < index2){ next = addTwoIndexNumbers(l1, index1,l2.next,index2 - 1); val2 = l2.val; }else{ next = addTwoIndexNumbers(l1.next,index1 - 1,l2.next,index2 - 1); val1 = l1.val; val2 = l2.val; } if (next.val >= 10){ sum = next.val / 10; next.val = next.val % 10; } res = new ListNode(val1 + val2 + sum); res.next = next; return res; } }
【2】2. 两数相加(这种由于是逆序的,直接遍历相加然后进位即可)
//时间1 ms 击败 100% //内存42.2 MB 击败 14.80% /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { //预先设置0节点 ListNode n1 = l1 , n2 = l2 ,zeroNode = new ListNode(0); ListNode tem , resNode = new ListNode(-1); ListNode head = resNode; int carryBit = 0; // 因为是逆序存储的所以可以直接加 while (n1 != null || n2 != null){ if (n1 == null) n1 = zeroNode; if (n2 == null) n2 = zeroNode; int value = n1.val+n2.val+carryBit; carryBit = value > 9 ? value / 10 : 0 ; value = value - carryBit*10; tem = new ListNode(value); head.next = tem; head = head.next; // 链表移动 n1 = n1.next; n2 = n2.next; } if (carryBit > 0){ tem = new ListNode(carryBit); head.next = tem; } return resNode.next; } }