leetcode代碼分類彙總之-鏈表

leetcode上鍊表的題目還算不少的,暫時收錄下面這些,可能有些被我分到其他部分去了。


Add Two Numbers

code:

class Solution {
public:
    ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) {
        int carry=0;
        ListNode* dummy = new ListNode(0),*ite=dummy;
        while(l1&&l2){
            int num = l1->val+l2->val+carry;
            carry = num/10;
            num %=10;
            ite->next = new ListNode(num);
            ite = ite->next;
            l1 = l1->next;
            l2 = l2->next;
        }
        l1 = l2?l2:l1;
        while(l1){
            int num = l1->val+carry;
            carry = num/10;
            num %=10;
            ite->next = new ListNode(num);
            ite=ite->next;
            l1 = l1->next;
        }
        if(carry){
            ite->next = new ListNode(carry);
            ite = ite->next;
        }
        ite->next = NULL;
        ite = dummy->next;
        delete dummy;
        return ite;
    }
};
這個題比較簡單,寫起來陷阱也不算多,一個改版是,如果鏈表的數字是倒過來的,怎麼做?也就是說鏈表頭是最高位的數字而不是最低位。
可以用遞歸做。


Partition List

這個是很久之前寫的代碼,O(n)時間+O(n)空間。應該在代碼風格和效率上還有可以優化的地方,暫時放在這裏,以後有好的代碼再補一個。

code:

class Solution {
public:
    ListNode *partition(ListNode *head, int x) {
        ListNode* p1 = head;
        if(head==NULL) return head;
        vector<int> vec;
        while(p1!=NULL){
            vec.push_back(p1->val);
            p1 = p1->next;
        }
        p1 = head;
        bool sign = true;
        int pos = 0;
        while(p1!=NULL){
            while(sign&&pos<vec.size()&&vec[pos]>=x)
                pos++;
            while(!sign&&pos<vec.size()&&vec[pos]<x)
                pos++;
            if(pos<vec.size()){
                p1->val = vec[pos++];
                p1 = p1->next;
            }else{
                if(!sign)
                    p1 = p1->next;
                sign = false;
                pos = 0;
            }
        }
        return head;
    }
};

關於這個題,還有一個很相似的版本,是要求O(n)時間+O(1)空間做到這個事情,不過給的不是鏈表,而是數組。我估摸着要是能做到,豈不是可以寫出一個穩定的快排??不知道怎麼搞。


Remove Duplicates from Sorted List

code:

class Solution {
public:
    ListNode *deleteDuplicates(ListNode *head) {
        ListNode *ite,*pre=head;
        if(!head) return head;
        ite = head->next;
        while(ite){
            if(ite->val==pre->val){
                pre->next = ite->next;
                delete ite;
            }else
                pre = ite;
            ite = pre->next;
        }
        return head;
    }
};

一開始沒注意是sorted,寫了個沒有sorted的代碼,順便也附上:

class Solution {
public:
    ListNode *deleteDuplicates(ListNode *head) {
        ListNode* dummy = new ListNode(1),*ite,*pre=dummy;;
        dummy->next = head;
        ite = head;
        set<int> s;
        while(ite){
            if(s.find(ite->val)!=s.end()){
                pre->next = ite->next;
                delete ite;
                ite=pre->next;
            }else{
                s.insert(ite->val);
                pre = ite;
                ite = ite->next;
            }
        }
        head = dummy->next;
        delete dummy;
        return head;
    }
};

Remove Duplicates from Sorted List II

code:

class Solution {
public:
    ListNode *deleteDuplicates(ListNode *head) {
        ListNode* dummy = new ListNode(1);
        dummy->next = head;
        bool sign = false;
        ListNode* pre = dummy,*ite=head;
        while(ite){
            if(sign||(ite->next&&ite->next->val==ite->val)){
                if(!ite->next||ite->next->val!=ite->val)
                  sign =false;
                else sign = true;
                pre->next = ite->next;
                delete ite;
            }else{
                pre=ite;
            }
            ite = pre->next;
        }
        head = dummy->next;
        delete dummy;
        return head;
    }
};

Remove Nth Node From End of List

code:

class Solution {
public:
    ListNode *removeNthFromEnd(ListNode *head, int n) {
        ListNode** ite = &head, *runner = head,*tmp;
        while(n--&&runner)
            runner = runner->next;
        if(n+1) return head;
        while(runner)
        {
            runner = runner->next;
            ite = &((*ite)->next);
        }
        tmp = *ite;
        (*ite) = (*ite)->next;
        delete tmp;
        return head;
    }
};
這個代碼的思路就是讓一個指針先走n步,那第一個指針到了尾之後,第二個指針就是倒數第n個,然後刪掉。

另一個思路是遞歸,遞歸結束時記錄當前是倒數第幾個節點:

class Solution {
public:
    int DelRecursive(ListNode* head,int n){
        if(!head) return 0;
        int k = DelRecursive(head->next,n);
        if(n==k){
            ListNode* tmp = head->next;
            head->next = head->next->next;
            delete tmp;
        }
        return k+1;
    }
    ListNode *removeNthFromEnd(ListNode *head, int n) {
        ListNode* dummy = new ListNode(0);
        dummy->next = head;
        DelRecursive(dummy,n);
        head = dummy->next;
        delete dummy;
        return head;
    }
};


Reverse Linked List II

class Solution {
public:
    ListNode *reverseBetween(ListNode *head, int m, int n) {
        ListNode* dummy = new ListNode(1),*ite = dummy,*tail;
        dummy->next = head;
        for(int i=1;i<m;i++)
          ite=ite->next;
        head = ite;
        tail = ite->next;
        //先斷開,再連接,順序很重要,第m個不用管
        for(int i=0;i<n-m;i++){
            ite = tail->next;
            tail->next = ite->next;
            ite->next = head->next;
            head->next = ite;
        }
        head = dummy->next;
        delete dummy;
        return head;
    }
};
記住先斷開再連接。

Swap Nodes in Pairs

爲了體驗一下指針的指針跟dummy head的區別,這個題分別用兩種方法做了一遍:

2D Pointer code:

class Solution {
public:
    ListNode *swapPairs(ListNode *head) {
        ListNode** ite = &head;
        while(*ite&&(*ite)->next)
        {
            ListNode* tmp = (*ite)->next;
            (*ite)->next = tmp->next;
            tmp->next = *ite;
            *ite = tmp;
            ite = &((*ite)->next->next);
        }
        return head;
    }
};
dummy head code:

class Solution {
public:
    ListNode *swapPairs(ListNode *head) {
        ListNode* dummy = new ListNode(0),*ite=dummy;
        dummy->next = head;
        while(ite->next&&ite->next->next){
            ListNode* tmp = ite->next->next;//保存要拿走的節點
            ite->next->next = tmp->next;  //刪除該節點
            tmp->next = ite->next;  //把該節點接到ite後面
            ite->next = tmp;
            ite = tmp->next;
        }
        ite = dummy->next;
        delete dummy;
        return ite;
    }
};




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章