package 链表;
/**
* https://leetcode-cn.com/problems/add-two-numbers/
*
* @author Huangyujun
*/
public class _2_两数相加 {
// 题目例子:输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
//输出:[8,9,9,9,0,0,0,1], 可以看到有进位这种东西
/**
* 自己尝试的递归(不香,写到一半放弃了)
* @param l1
* @param l2
* @return
*/
// public ListNode addTwoNumbers2(ListNode l1, ListNode l2) {
// if(l1 == null && l2 == null) return null;
// //其中一个长度为 0
// if(l1 == null && l2 != null) return l2;
// if(l1 != null && l2 == null) return l1;
//
// ListNode l = addTwoNumbers2(l1.next, l2.next);
// //剩下 l1 和 l2
// int sum = l1.val + l2.val;
// int carry = sum / 10;
// ListNode head = null;
// if(carry < 0) {
// head = new ListNode(sum);
// head.next = l;
// }else {//进位的话,需要进行传递
// int val = sum % 10;
// head = new ListNode(val);
// ListNode temp = l;
// while(temp != null) {//这里边也需要考虑又再次进位了,递归不香了
//// temp.val
// }
// }
// return head;
// }
//官网的方法:官网用 || 把链表是否为空的所有情况都考虑
//(我是详细的分成四种情况 l1、l2同时为空; 11 为空,12 不为空; l1不为空,l2 为空; l1 、 l2 同时不为空)
//而且我分析到 l1 、 l2 同时不为空 时,使用while(l1 != null && l2 != null), 后边就还得再次考虑 l1 (l2)链表还有剩下结点没有被访问到呢
/**
* 官网的框架:
while (l1 != null || l2 != null){
if (l1 != null) {
l1 = l1.next;
}
if (l2 != null) {
l2 = l2.next;
}
}
比我的框架少写了好多重复代码啦
* @author Huangyujun
*
*/
//然后 在 || 的情况下,拿到头结点的初始值(经过是否为空,空的初始值 为 0,否则就是头结点的值)
class Solution2 {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode head = null, tail = null; //从无到有,硬生生构建出一条链表(需要有两个指针(或者一个头结点和一个指针):其中一个指针用来实现遍历到下一个位置去创建结点,然后next 连起来,一个就是head啦)
int carry = 0;
while (l1 != null || l2 != null) {
//拿到头结点的初始值(经过是否为空,空的初始值 为 0,否则就是头结点的值)
int n1 = l1 != null ? l1.val : 0;
int n2 = l2 != null ? l2.val : 0;
int sum = n1 + n2 + carry;
if (head == null) { //构建第一个结点时
head = tail = new ListNode(sum % 10);
} else {
tail.next = new ListNode(sum % 10);
tail = tail.next;
}
carry = sum / 10;
if (l1 != null) {
l1 = l1.next;
}
if (l2 != null) {
l2 = l2.next;
}
}
if (carry > 0) { //最后一位的考虑
tail.next = new ListNode(carry);
}
return head;
}
}
//自己写的就是代码太啰嗦了(思路跟官网一样)
public ListNode addTwoNumbers2(ListNode l1, ListNode l2) {
if(l1 == null && l2 == null) return null;
if(l1 == null && l2 != null) return l2;
if(l1 != null && l2 == null) return l1;
ListNode ptr1 = l1;
ListNode ptr2 = l2;
ListNode head = new ListNode(0);
ListNode tmp = head;
int carry = 0;
int sum = 0;
while(ptr1 != null && ptr2 != null) {
sum = ptr1.val + ptr2.val + carry; //考虑到进位的情况
//考虑进位
carry = sum / 10;
sum %= 10;
ListNode p = new ListNode(sum);
tmp.next = p;
tmp = p;
ptr1 = ptr1.next;
ptr2 = ptr2.next;
}
while(ptr1 != null) {
//tmp 继续走
sum = ptr1.val + carry; //考虑到进位的情况
carry = sum / 10;
sum %= 10;
ListNode p = new ListNode(sum);
tmp.next = p;
tmp = p;
ptr1 = ptr1.next;
}
while(ptr2 != null) {
//tmp 继续走
sum = ptr2.val + carry; //考虑到进位的情况
carry = sum / 10;
sum %= 10;
ListNode p = new ListNode(sum);
tmp.next = p;
tmp = p;
ptr2 = ptr2.next;
}
if(carry != 0){//最后一位处理
ListNode p = new ListNode(carry);
tmp.next = p;
}
return head.next;
}
}