翻转链表
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
l1 = reverseList(l1);
l2 = reverseList(l2);
/**
* 最后还要反转一下
*/
return reverseList(addNumbers(l1, l2));
}
/**
* 先反转两个链表
*/
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode tem = curr.next;
curr.next = prev;
prev = curr;
curr = tem;
}
return prev;
}
/**
* 转换为逆序后再相加
*/
public ListNode addNumbers(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(-1);
ListNode head = dummyHead;
ListNode cur1 = l1;
ListNode cur2 = l2;
int n;
int sum;
int rest = 0;
while (cur1 != null || cur2 != null){
sum = (cur1 == null ? 0 : cur1.val) + (cur2 == null ? 0 : cur2.val) + rest;
n = sum % 10;
rest = sum / 10;
head.next = new ListNode(n);
head = head.next;
if (cur1 != null){
cur1 = cur1.next;
}
if (cur2 != null){
cur2 = cur2.next;
}
}
if (rest == 1){
head.next = new ListNode(rest);
}
return dummyHead.next;
}
}
/**
* 时间复杂度 O(n)
* 空间复杂度 O(1)
*/
不翻转链表——用栈存储
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
/**
* 将两个链表压入栈中,这样出栈时的顺序就是《2. 两数相加》
* 最后将结果也要存入栈中,打印的顺序就是从高位到低位
*/
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
Stack<Integer> stack = new Stack<>();
ListNode dummyHead = new ListNode(-1);
ListNode head = dummyHead;
ListNode cur1 = l1;
ListNode cur2 = l2;
while (cur1 != null){
stack1.push(cur1.val);
cur1 = cur1.next;
}
while (cur2 != null){
stack2.push(cur2.val);
cur2 = cur2.next;
}
int sum;
int n;
int rest = 0;
while (!stack1.empty() || !stack2.empty()){
sum = (stack1.empty() ? 0 : stack1.pop()) + (stack2.empty() ? 0 : stack2.pop()) + rest;
n = sum % 10;
rest = sum / 10;
stack.push(n);
}
if (rest != 0){
stack.push(rest);
}
while (!stack.empty()){
head.next = new ListNode(stack.pop());
head = head.next;
}
return dummyHead.next;
}
}
/**
* 时间复杂度 O(n)
* 空间复杂度 O(n)
*/
优化1——加和时动态翻转链表
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
/**
* 将两个链表压入栈中,这样出栈时的顺序就是《2. 两数相加》
* 可以在存储结果时就翻转链表,这样就不用再使用栈来存储
*/
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
ListNode prev = null;
ListNode cur1 = l1;
ListNode cur2 = l2;
while (cur1 != null){
stack1.push(cur1.val);
cur1 = cur1.next;
}
while (cur2 != null){
stack2.push(cur2.val);
cur2 = cur2.next;
}
int sum;
int n;
int rest = 0;
/**
* 只要有一个链表还有元素,或者进位数不为0,循环就继续
* 将最后的rest == 1的情况合并到循环中
*/
while (!stack1.empty() || !stack2.empty() || rest != 0){
sum = (stack1.empty() ? 0 : stack1.pop()) + (stack2.empty() ? 0 : stack2.pop()) + rest;
n = sum % 10;
rest = sum / 10;
/**
* 存储结果时就翻转链表,最后一个节点始终是头节点
*/
ListNode cur = new ListNode(n);
cur.next = prev;
prev = cur;
}
return prev;
}
}
/**
* 时间复杂度 O(n)
* 空间复杂度 O(n)
*/
https://leetcode-cn.com/problems/add-two-numbers-ii/