[LeetCode] 369. Plus One Linked List 鏈表加一運算


 

Given a non-negative integer represented as non-empty a singly linked list of digits, plus one to the integer.

You may assume the integer do not contain any leading zero, except the number 0 itself.

The digits are stored such that the most significant digit is at the head of the list.

Example :

Input: [1,2,3]
Output: [1,2,4]

 

這道題給了我們一個鏈表,用來模擬一個三位數,表頭是高位,現在讓我們進行加1運算,這道題的難點在於鏈表無法通過坐標來訪問元素,只能通過遍歷的方式進行,而這題剛好讓我們從鏈尾開始操作,從后往前,遇到進位也要正確的處理,最后還有可能要在開頭補上一位。那么我們反過來想,如果鏈尾是高位,那么進行加1運算就方便多了,直接就可以邊遍歷邊進行運算處理,那么我們可以做的就是先把鏈表翻轉一下,然后現在就是鏈尾是高位了,我們進行加1處理運算結束后,再把鏈表翻轉回來即可,參見代碼如下:

 

解法一:

class Solution {
public:
    ListNode* plusOne(ListNode* head) {
        if (!head) return head;
        ListNode *rev_head = reverse(head), *cur = rev_head, *pre = cur;
        int carry = 1;
        while (cur) {
            pre = cur;
            int t = cur->val + carry;
            cur->val = t % 10;
            carry = t / 10;
            if (carry == 0) break;
            cur = cur->next;
        }
        if (carry) pre->next = new ListNode(1);
        return reverse(rev_head);
    }
    ListNode* reverse(ListNode *head) {
        if (!head) return head;
        ListNode *dummy = new ListNode(-1), *cur = head;
        dummy->next = head;
        while (cur->next) {
            ListNode *t = cur->next;
            cur->next = t->next;
            t->next = dummy->next;
            dummy->next = t;
        }
        return dummy->next;
    }
};

 

我們也可以通過遞歸來實現,這樣我們就不用翻轉鏈表了,通過遞歸一層一層的調用,最先處理的是鏈尾元素,我們將其加1,然后看是否有進位,返回進位,然后回溯到表頭,加完進位,如果發現又產生了新的進位,那么我們在最開頭加上一個新節點即可,參見代碼如下:

 

解法二:

class Solution {
public:
    ListNode* plusOne(ListNode* head) {
        if (!head) return head;
        int carry = helper(head);
        if (carry == 1) {
            ListNode *res = new ListNode(1);
            res->next = head;
            return res;
        }
        return head;
    }
    int helper(ListNode *node) {
        if (!node) return 1;
        int carry = helper(node->next);
        int sum = node->val + carry;
        node->val = sum % 10;
        return sum / 10;
    }
};

 

下面這種方法比較巧妙了,思路是遍歷鏈表,找到右起第一個不為9的數字,如果找不到這樣的數字,說明所有數字均為9,那么在表頭新建一個值為0的新節點,進行加1處理,然后把右邊所有的數字都置為0即可。舉例來說:

比如1->2->3,那么第一個不為9的數字為3,對3進行加1,變成4,右邊沒有節點了,所以不做處理,返回1->2->4。

再比如說8->9->9,找第一個不為9的數字為8,進行加1處理變成了9,然后把后面的數字都置0,得到結果9->0->0。

再來看9->9->9的情況,找不到不為9的數字,那么再前面新建一個值為0的節點,進行加1處理變成了1,把后面的數字都置0,得到1->0->0->0。

 

解法三:

class Solution {
public:
    ListNode* plusOne(ListNode* head) {
        ListNode *cur = head, *right = NULL;
        while (cur) {
            if (cur->val != 9) right = cur;
            cur = cur->next;
        }
        if (!right) {
            right = new ListNode(0);
            right->next = head;
            head = right;
        }
        ++right->val;
        cur = right->next;
        while (cur) {
            cur->val = 0;
            cur = cur->next;
        }
        return head;
    }
};

 

最后這種解法是解法二的迭代寫法,我們用到棧,利用棧的先進后出機制,就可以實現從后往前的處理節點,參見代碼如下:

 

解法四:

class Solution {
public:
    ListNode* plusOne(ListNode* head) {
        stack<ListNode*> s;
        ListNode *cur = head;
        while (cur) {
            s.push(cur);
            cur = cur->next;
        }
        int carry = 1;
        while (!s.empty() && carry) {
            ListNode *t = s.top(); s.pop();
            int sum = t->val + carry;
            t->val = sum % 10;
            carry = sum / 10;
        }
        if (carry) {
            ListNode *new_head = new ListNode(1);
            new_head->next = head;
            head = new_head;
        }
        return head;
    }
};

 

類似題目:

Plus One

 

參考資料:

https://leetcode.com/problems/plus-one-linked-list/

https://leetcode.com/discuss/111165/2-accepted-java-solution

https://leetcode.com/discuss/111205/simple-solution-use-recursion

https://leetcode.com/discuss/111157/9-lines-recursive-without-helper

https://leetcode.com/discuss/111155/java-stack-solution-with-inline-explanation

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM