我要好offer之 鏈表大總結

單鏈表是一種遞歸結構,能夠將單鏈表看做特殊的二叉樹(我把它叫作一叉樹)html

單鏈表的定義:node

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

1. O(1)時間刪除結點spa

ListNode* DeleteNode(ListNode* pHead, ListNode* deletedNode) {
    assert(pHead != NULL && deletedNode != NULL);
    ListNode newHead(-1);
    newHead.next = pHead;
    if (pHead == deletedNode) {
        newHead->next = pHead->next;
        delete deletedNode;
        deketedNode = NULL;
        return newHead.next;
    } else {
        if (deleteNode->next == NULL) {
            ListNode* cur = pHead;
            while (cur->next != deleteNode) {
                cur = cur->next;
            }
            cur->next = NULL;
            delete deletedNode;
            deletedNode = NULL;
            return newHead.next;
        } else {
            ListNode* nextNode = deletedNode->next;
            deletedNode->val = nextNode->val;
            deletedNode->next = nextNode->next;
            delete nextNode;
            nextNode = NULL;
            return newHead.next;
        }
    }
}

 

2. 單鏈表反轉指針

ListNode* ReverseList(ListNode* pHead) {
    if (pHead == NULL || pHead->next == NULL) {
        return pHead;
    }
    ListNode* tail = pHead;
    ListNode* cur = pHead->next;
    while (cur != NULL) {
        ListNode* nextNode = cur->next;
        cur->next = pHead;
        pHead = cur;
        cur = nextNode;
    }
    tail->next = NULL;
    return pHead;
}

 

3. 單鏈表倒數第k個結點code

ListNode* KthNode(ListNode* pHead, int k) {
    assert(pHead != NULL && k > 0);
    ListNode* first = pHead;
    ListNode* second = pHead;
    while (first != NULL && k > 0) {
        first = first->next;
        --k;
    }
    if (first == NULL) {
        if (k == 0) {
            return pHead;
        } else {
            return NULL;
        }
    }
    while (first != NULL) {
        first = first->next;
        second = second->next;
    }
    return second;
}

 

4. 單鏈表反轉部分區間htm

5. 單鏈錶快速排序的一趟劃分blog

6. 單鏈表去掉重複元素排序

7. 單鏈表旋轉遞歸

8. 單鏈表成對交換節點leetcode

9. 有序單鏈表歸併排序

10. 單鏈表加法運算

11. 單鏈表是否存在環,環的位置

12. 兩個單鏈表的第一個公共結點

13. 單鏈表歸併排序

class Solution {
public:
    ListNode *sortList(ListNode *head) {
        if (head == NULL || head->next == NULL) {
            return head;
        }
        
        ListNode* slow = head;
        ListNode* fast = head;
        //快慢指針找鏈表中間結點
        while (fast != NULL && fast->next != NULL && fast->next->next != NULL) {
            slow = slow->next;
            fast = fast->next->next;
        }
        ListNode* list1 = head;
        ListNode* list2 = slow->next;
        slow->next = NULL;
        ListNode* sortList1 = sortList(list1);
        ListNode* sortList2 = sortList(list2);
        ListNode* res = mergeSortList(sortList1, sortList2);
        return res;
    }
    
    ListNode* mergeSortList(ListNode* list1, ListNode* list2) {
        if (list1 == NULL) return list2;
        if (list2 == NULL) return list1;
        ListNode newHead(-1);
        ListNode* cur = &newHead;
        ListNode* node1 = list1;
        ListNode* node2 = list2;
        while (node1 != NULL && node2 != NULL) {
            if (node1->val <= node2->val) {
                cur->next = node1;
                node1 = node1->next;
                cur = cur->next;
            } else {
                cur->next = node2;
                node2 = node2->next;
                cur = cur->next;
            }
        }
        while (node1 != NULL) {
            cur->next = node1;
            node1 = node1->next;
            cur = cur->next;
        }
        while (node2 != NULL) {
            cur->next = node2;
            node2 = node2->next;
            cur = cur->next;
        }
        return newHead.next;
    }
};
相關文章
相關標籤/搜索