微信公衆號:程序員Alex
關注可瞭解更多的編程知識。問題或建議,請公衆號留言;
公衆號回覆加羣
即可加入刷題大隊
歡迎一起加入刷題大隊,
如果你覺得文章對你有幫助,歡迎轉發分享
給你兩個 非空 鏈表來代表兩個非負整數。數字最高位位於鏈表開始位置。它們的每個節點只存儲一位數字。將這兩數相加會返回一個新的鏈表。
你可以假設除了數字 0 之外,這兩個數字都不會以零開頭
示例
輸入:(7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 8 -> 0 -> 7
解題思路
鏈表不能翻轉,且鏈表頭結點爲高位,所以引入棧來解決問題,棧頂元素爲低位,棧底爲高位。
- 遍歷鏈表入棧,得到stack1和stack2。
- 定義進位carry,和最終結果result。
- stack1 和 stack2 執行出棧操作,直至棧頂爲空。
- 分別獲取棧頂元素,默認值爲0;
- 棧頂元素和carry相加,判斷是否有進位。有進位carry賦值爲1,反之carry爲0;
- 創建新的節點,將新節點的next指向result(新節點爲高位)
- 則新節點爲新的result
代碼實現
public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
// 利用棧的先進後出原則實現加法
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
// 將鏈表數據入棧,棧頂爲低位
while ((l1 != null) || (l2 != null)) {
if (l1 != null) {
stack1.push(l1.val);
l1 = l1.next;
}
if (l2 != null) {
stack2.push(l2.val);
l2 = l2.next;
}
}
int num1 = 0;
int num2 = 0;
// 存儲進位數據
int carry = 0;
// 最終結果
ListNode result = null;
// 出棧,出棧過程是計算相對低位數據的過程
while (!stack1.empty() || !stack2.empty() || carry == 1) {
num1 = stack1.empty() ? 0 : stack1.pop();
num2 = stack2.empty() ? 0 : stack2.pop();
ListNode listNode = new ListNode(0);
// 有進位的情況
if (num1 + num2 + carry > 9) {
listNode.val = num1 + num2 + carry - 10;
carry = 1;
} else {
// 無進位
listNode.val = num1 + num2 + carry;
carry = 0;
}
// 原有高位降一位
listNode.next = result;
// 設置最新高位
result = listNode;
}
return result;
}
複雜度分析
時間複雜度
時間複雜度在於對鏈表的遍歷。假設l1的長度是 m, l2 的長度是 n,則時間複雜度爲O(max(m,n))
空間複雜度
O(n+m)
完整代碼上傳至github
https://github.com/tinet-shenjg/leetCode4J
刷題大隊
歡迎關注公衆號【程序員Alex】回覆:‘加羣’加入刷題大隊,一起刷題