链表笔记

来源:互联网 发布:单身狗的嘲讽知乎 编辑:程序博客网 时间:2024/06/16 16:27

链表相关的笔记

206. Reverse Linked List

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* reverseList(ListNode* head) {        ListNode* pPre = NULL;        ListNode* pCur = head;        ListNode* pNext = NULL;        while(pCur){            pNext = pCur->next;            pCur->next = pPre;            pPre = pCur;            pCur = pNext;        }        return pPre;    }};

92. Reverse Linked List II

/* 整体思路: * 在反转链表的基础上,记录好左侧部分和右侧部分结点,然后和局部反转后的链表拼接起来即可 *//** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* reverseBetween(ListNode* head, int m, int n) {        if (head == NULL || m < 1 || n < m)            return NULL;        ListNode* dummyHead = new ListNode(-1);        dummyHead->next = head;        ListNode* pCur = dummyHead;        ListNode* pPre = NULL;        ListNode* pNext = NULL;        // 让pCur指向m结点的前一个结点,存储为left        for (int i = 1; i <= m - 1; ++i)            pCur = pCur->next;        ListNode* left = pCur;        // pCur指向m结点        pCur = pCur->next;        // 反转部分的尾结点存储为right        ListNode* right = pCur;        // 对m到n位置的数进行反转        // 反转后这部分头结点为pPre        // 尾结点需要事先存储为right        // pNext为n右侧部分的头结点        // right -> pNext        // pPre接上m左侧部分 left->pPre        // pNext接上n右侧部分        for (int i = m; i <= n; ++i){            pNext = pCur->next;            pCur->next = pPre;            pPre = pCur;            pCur = pNext;        }        // left -> reverse part head: pPre -> ... -> reverse part tail:right ->pNext        left->next = pPre;        right->next = pNext;        return dummyHead->next;    }};

通过vector创建链表、打印链表、删除链表释放空间

ListNode* createLinkedList(vector<int> v){    if (v.empty())        return NULL;    ListNode* head = new ListNode(v[0]);    ListNode* pCur = head;    for (int i = 1; i < v.size(); ++i){        pCur->next = new ListNode(v[i]);        pCur = pCur->next;    }    return head;}void printLinkedList(ListNode* head){    while (head != NULL){        cout << head->val << " -> ";        head = head->next;    }    cout << "NULL" << endl;}void deleteLinkedList(ListNode* head){    ListNode* pCur = head;    while (pCur){        ListNode* delNode = pCur;        pCur = pCur->next;        delete delNode;    }    return;}

83. Remove Duplicates from Sorted List

/* 整体思路: * 当前结点和下一个结点比较,相同则删除下一个结点,否则直接滑动一个结点 *//** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* deleteDuplicates(ListNode* head) {        if(head == NULL)            return NULL;        ListNode* pCur = head;        while(pCur && pCur->next){            if(pCur->val == pCur->next->val){                ListNode* delNode = pCur->next;                pCur->next = pCur->next->next;                delete delNode;            }else                pCur = pCur->next;                        }        return head;    }};

86. Partition List

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* partition(ListNode* head, int x) {        if (head == NULL)            return NULL;        ListNode* pCur = head;        ListNode* left = new ListNode(-1);        ListNode* right = new ListNode(-1);        ListNode* l = left;        ListNode* r = right;        while (pCur){            if (pCur->val < x){                l->next = pCur;                l = l->next;                //pCur_left = NULL;            }            else{                r->next = pCur;                r = r->next;            }            pCur = pCur->next;        }        // r的next指针必须置为0,因为它是right的最后一个结点        r->next = NULL;        l->next = right->next;        return left->next;    }};

328. Odd Even Linked List

// 看看代码,画画图就懂了/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* oddEvenList(ListNode* head) {        if(head == NULL)            return NULL;        ListNode* first = head;        ListNode* second = head->next;        ListNode* temp = second;        while(second && second->next){            first->next = second->next;            first = first->next;            second->next = first->next;            second = second->next;        }        first->next = temp;        return head;    }};

2. Add Two Numbers

// 处理好进位即可,尤其是最后一位为1时,不要忘记单独处理/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {        int jw = 0;        int sum = 0;        ListNode* head = new ListNode(0);        ListNode* pCur = head;        while(l1 || l2){            sum = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + jw;            jw = sum / 10;            pCur->next = new ListNode(sum % 10);            pCur = pCur->next;            l1 = (l1 ? l1->next : l1);            l2 = (l2 ? l2->next : l2);        }        if(jw)            pCur->next = new ListNode(1);        return head->next;    }};

445. Add Two Numbers II

// 整体思路:用栈即可/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {        stack<ListNode*> s1;        stack<ListNode*> s2;        stack<ListNode*> result;        while(l1){            s1.push(l1);            l1 = l1->next;        }        while(l2){            s2.push(l2);            l2 = l2->next;        }        int jw = 0;        while(!s1.empty() || !s2.empty()){            if(!s1.empty()){                l1 = s1.top();                s1.pop();            }else                l1 = NULL;            if(!s2.empty()){                l2 = s2.top();                s2.pop();            }else                l2 = NULL;            int sum = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + jw;            jw = sum / 10;            result.push(new ListNode(sum % 10));        }        // 注意最后的进位        if(jw)            result.push(new ListNode(1));        // 将结果依次出栈        ListNode* newHead = result.top();        result.pop();        ListNode* pCur = newHead;        while(!result.empty()){            pCur->next = result.top();            result.pop();            pCur = pCur->next;        }        return newHead;    }};

设立链表的虚拟头结点dummyHead

203. Remove Linked List Elements

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* removeElements(ListNode* head, int val) {        if(head == NULL)            return NULL;        ListNode* dummyHead = new ListNode(0);        dummyHead->next = head;        ListNode* pCur = dummyHead;        while(pCur && pCur->next){            if(pCur->next->val == val){                ListNode* delNode = pCur->next;                pCur->next = pCur->next->next;                delete delNode;            }else                pCur = pCur->next;        }        return dummyHead->next;    }};

82. Remove Duplicates from Sorted List II

// 用两个指针一前一后遍历/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* deleteDuplicates(ListNode* head) {        if(head == NULL)            return NULL;        ListNode* newHead = new ListNode(0);        newHead->next = head;        ListNode* pCur = newHead;        ListNode* pre = head->next;        ListNode* behind = head;        while(pre != NULL){            if(pre->val != behind->val){                pCur->next = behind;                pCur = pCur->next;                pre = pre->next;                behind = behind->next;            }else{                while(pre && pre->val == behind->val){                    // 直到pre为空 或者 不等于behind                    pre = pre->next;                }                while(behind != pre){                    ListNode* delNode = behind;                    behind = behind->next;                    delete delNode;                }                pCur->next = behind;                if(pre == NULL)                    return newHead->next;                pre = pre->next;            }        }        return newHead->next;    }};

21. Merge Two Sorted Lists

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {        ListNode* newHead = new ListNode(0);        ListNode* pCur = newHead;        while(l1 || l2){            if(l1 == NULL){                pCur->next = l2;                break;            }            if(l2 == NULL){                pCur->next = l1;                break;            }            if(l1->val < l2->val){                pCur->next = l1;                l1 = l1->next;                pCur = pCur->next;            }else{                pCur->next = l2;                l2 = l2->next;                pCur = pCur->next;            }        }        return newHead->next;    }};


24. Swap Nodes in Pairs

// 实现分析好需要几个临时指针变量// 画图分析一下指针变换顺序即可/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* swapPairs(ListNode* head) {        ListNode* dummyHead = new ListNode(0);        // 指向dummyHead的指针        ListNode* d_pCur = dummyHead;        dummyHead->next = head;        ListNode* pCur = head;        // 至少两个非空结点才swap        while (pCur && pCur->next) {            ListNode* temp = pCur->next;            ListNode* pNext = pCur->next;            pCur->next = pCur->next->next;            pNext->next = pCur;            d_pCur->next = temp;            d_pCur = d_pCur->next->next;            pCur = pCur->next;        }        return dummyHead->next;    }};

25. Reverse Nodes in k-Group


147. Insertion Sort List

// 链表排序,这段代码多体会一下/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode *insertionSortList(ListNode *head) {        ListNode *sortedHead = new ListNode(-1);        while(head != NULL){            //保存head的下一个结点            ListNode *temp = head->next;            ListNode *cur = sortedHead;            while(cur->next != NULL && cur->next->val < head->val)                cur = cur->next;            //插入            head->next = cur->next;            cur->next = head;            //恢复head为head的下一个结点            head = temp;        }        return sortedHead->next;    }};

148. Sort List


237. Delete Node in a Linked List

// 将后一个结点的值赋值给当前结点// 然后删除后一个结点即可/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    void deleteNode(ListNode* node) {        if(node == NULL)            return;        // 题目已经强调不是尾结点, 不需要考虑        // if(node->next == NULL)            // do something        node->val = node->next->val;        ListNode* delNode = node->next;        node->next = delNode->next;        delete delNode;        return;       }};

双指针技术


19. Remove Nth Node From End of List

// 两个指针一前一后扫描一遍即可,其中一个指针先行/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* removeNthFromEnd(ListNode* head, int n) {        ListNode* dummyHead = new ListNode(0);        dummyHead->next = head;        ListNode* pre = dummyHead;        ListNode* behind = dummyHead;        while(n--)            pre = pre->next;        while(pre->next){            pre = pre->next;            behind = behind->next;        }        // behind达到待删除结点的前驱        ListNode* delNode = behind->next;        behind->next = delNode->next;        delete delNode;        return dummyHead->next;    }};

61. Rotate List


/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* rotateRight(ListNode* head, int k) {        if (head == NULL)            return NULL;        // k 的大小可能大于链表的长度: 先计算链表长度,k = k % length        ListNode* pCur = head;        int length = 0;        while (pCur){            ++length;            pCur = pCur->next;        }        k = k % length;        // k如果等于0,不需要旋转        if (k == 0)            return head;        // 原始链表:left_start ,..., left_end, right_start, ..., right_end        // 旋转结果:right_start, ..., right_end, left_start, ..., left_end        // 找到右半部分的前驱,也就是左半部分的最后一个结点left_end        // left_start就是head,不需要寻找了        ListNode* left_end = head;        for (int i = 1; i < length - k; ++i){            left_end = left_end->next;        }        // right_start是left_end的下一个结点        ListNode* right_start = left_end->next;        ListNode* right_end = right_start;        // right_end是尾结点        while (right_end->next != NULL)            right_end = right_end->next;        right_end->next = head;        left_end->next = NULL;        return right_start;    }};

143. Reorder List

// 分三步:// 1.找到中间结点// 2.将右半侧反转// 3.合并两个链表/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    void reorderList(ListNode* head) {        if(head == NULL || head->next == NULL)            return;        // 找到中间结点        ListNode* p1 = head;        ListNode* p2 = head->next;        while(p2 && p2->next){            p1 = p1->next;            p2 = p2->next->next;        }        ListNode* middleHead = p1->next;        p1->next = NULL;        // 反转middleHead开始的部分        ListNode* pPre = NULL;        ListNode* pCur = middleHead;        ListNode* pNext = NULL;        while(pCur){            pNext = pCur->next;            pCur->next = pPre;            pPre = pCur;            pCur = pNext;        }        middleHead = pPre;        // 合并        for (p1 = head, p2 = middleHead; p1; ) {            ListNode* temp = p1->next;            p1->next = p2;            p1 = p2;            p2 = temp;        }    }};

234. Palindrome Linked List

// 思路:创建一个辅助栈,依次比较即可// 此题还有空间更高效的算法:O(1)空间复杂度,O(n)时间复杂度/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    bool isPalindrome(ListNode* head) {        stack<ListNode*> s;        ListNode* pCur = head;        while(pCur){            s.push(pCur);            pCur = pCur->next;        }        pCur = head;        while(!s.empty()){            ListNode* temp = s.top();            s.pop();            if(temp->val != pCur->val)                return false;            pCur = pCur->next;        }        return true;    }};