您现在的位置是:首页 >其他 >从零学算法网站首页其他
从零学算法
简介从零学算法
2. 两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例 2:
输入:l1 = [0], l2 = [0]
输出:[0]
示例 3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]
- 我的原始人解法:首先按照现在从前往后的顺序遍历两个链表就是从个位开始相加,正好省的我反转链表,定义一个变量记录是否满十进一,然后根据相加的结果不断创建新结点,并且不断更新头结点,如果最后满十进一变量仍为 true 则再加一位 1(否则 99 + 1 得到 00 了),最后的链表反转即可。
-
public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode l = null; boolean addOne = false; while(l1!=null || l2!=null){ int val; // l1 的加完了那直接加 l2 的即可,l2 的加完了同理,否则两数相加 if(l1 == null){ val = l2.val; l2=l2.next; }else if (l2 == null){ val = l1.val; l1=l1.next; }else{ val = l1.val + l2.val; l1=l1.next; l2=l2.next; } // 如果满十进一,我加上进的 1 if(addOne) val++; // 如果新结果小于十,之后就暂时不进一了 if(val < 10){ addOne=false; }else{ // 新结果还大于等于 10 那就继续进一 val%=10; addOne=true; } ListNode t = new ListNode(val,l); l = t; } if(addOne){ ListNode t = new ListNode(1,l); l = t; } return reverse(l); } // 从前往后遍历链表,不断把结果加到新链表尾部就实现了链表反转 public ListNode reverse(ListNode l) { ListNode r = null; while(l != null){ // 暂时保存头结点下一个结点 ListNode t = l.next; // 把摘出来的头结点的下一位连上要返回的结果链表 r // 上面要是不暂存下一个结点,l 都没法继续遍历了 l.next = r; // 更新头结点 r=l; // 继续下一位 l=t; } return r; }
- 他人解法:既然位数不一定相等,那就补 0 使其相等。(关于返回的结果链表,我是不断 new ListNode 最后反转链表。他人题解是创建两个链表第一个为记录头结点的链表 pre,让第二个链表等于 pre,然后让第二个链表不断往后加结点并遍历到下一结点,最后返回 pre.next 即可。)
-
public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode pre = new ListNode(0); ListNode cur = pre; int carry = 0; while(l1 != null || l2 != null) { // 补 0 int x = l1 == null ? 0 : l1.val; int y = l2 == null ? 0 : l2.val; int sum = x + y + carry; // 这么写就省的每次判断是否要加上进的 1 了 carry = sum / 10; sum = sum % 10; // 这就是我说的第二个链表不断往后加结点并遍历到下一结点 cur.next = new ListNode(sum); cur = cur.next; if(l1 != null) l1 = l1.next; if(l2 != null) l2 = l2.next; } if(carry == 1) { cur.next = new ListNode(carry); } return pre.next; }
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。