方法1:用栈
不对原始链表进行修改,使用栈将链表逆序,然后再用头插法创建链表,注意这里是头插法,不然结果会逆序。
代码:
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
Stack<Integer> stack1 = new Stack<Integer> ();
Stack<Integer> stack2 = new Stack<Integer> ();
while (l1 != null){
stack1.push(l1.val);
l1 = l1.next;
}
while (l2 != null){
stack2.push(l2.val);
l2 = l2.next;
}
int carry = 0;
ListNode ans = new ListNode(-1);
ListNode temp = null;
while ((!stack1.isEmpty()) || (!stack2.isEmpty())){
int n1 = stack1.isEmpty() ? 0 : stack1.pop();
int n2 = stack2.isEmpty() ? 0 : stack2.pop();
ans.next = new ListNode((n1 + n2 + carry) % 10);
ans.next.next = temp;
carry = (n1 + n2 + carry) / 10;
temp = ans.next;
}
if (carry == 1){
ans.next = new ListNode(carry);
ans.next.next = temp;
}
return ans.next;
}
时间复杂度:O(max(m, n)),其中 m 与 n 分别为两个链表的长度。我们需要遍历每个链表。
空间复杂度:O(m + n),其中 m 与 n 分别为两个链表的长度。这是我们把链表内容放入栈中所用的空间。
方法2
编写将链表逆序地函数,这样可以节省栈的空间,但是在新建链表的时候还是要用头插法才行。
相当于leetcode 2 + leetcode 206 + 头插法
代码:
public ListNode reverseList(ListNode head) {
ListNode temp1 = null;
ListNode temp = head;
ListNode temp2;
while (temp != null){
temp2 = temp.next;
temp.next = temp1;
temp1 = temp;
temp = temp2;
}
return temp1;
}
public ListNode addTwoNumbers1(ListNode l1, ListNode l2){
ListNode temp1 = reverseList(l1);
ListNode temp2 = reverseList(l2);
ListNode dummy = new ListNode(-1);
ListNode temp = null;
int carry = 0;
while (temp1 != null || temp2 != null) {
int n1 = temp1 != null ? temp1.val : 0;
int n2 = temp2 != null ? temp2.val : 0;
dummy.next = new ListNode((n1 + n2 + carry) % 10);
carry = (n1 + n2 + carry) / 10;
dummy.next.next = temp;
temp = dummy.next;
temp1 = temp1 == null ? null : temp1.next;
temp2 = temp2 == null ? null : temp2.next;
}
if (carry == 1){
dummy.next = new ListNode(carry);
dummy.next.next = temp;
}
l1 = reverseList(temp1);
l2 = reverseList(temp2);
return dummy.next;
}