zoukankan      html  css  js  c++  java
  • LeetCode链表解题模板

    一、通用方法以及题目分类

    0、遍历链表

    方法代码如下,head可以为空:

    ListNode* p = head;
    while(p!=NULL)
        p = p->next;

    可以在这个代码上进行修改,比如要计算链表的长度:

    ListNode* p = head;
    int num = 0;
    while(p!=NULL){
        num++;
        p = p->next;
    }

    如果要找到最后的节点,可以更改while循环中的条件,只不过需要加上head为NULL时的判断

    if(!head) return head;
    ListNode* p = head;
    while(p->next!=NULL){
        p = p->next;
    }

    还可以使用两个指针,一个用来遍历,一个用来记录前一个

    ListNode* p_before = NULL;
    ListNode* p = head;
    while(p!=NULL){
        p_before = p;
        p = p->next;
    }

    1、在head之前加上一个节点来简化计算

    头结点的操作不同于中间节点,所以需要额外判断。穿插在很多题目中。

    LeetCode 203 删除节点中的元素:https://leetcode.com/problems/remove-linked-list-elements/description/

    2、两链表合并操作

    l1代表链表1的头,l2代表链表2的头,通过以下方式来遍历链表(或是将while循环中的&&改成||)

    while循环中如果是&&,则退出循环需要处理一个为空、一个还有的情况。如果while循环中为||,则在while循环体中需要判断其中一个为空的情况

    还可以联合前一种方式,在head之前加上一个节点来简化计算

    while(l1!=NULL && l2!=NULL){
        if(l1 != NULL){
            //operator on l1
            l1 = l1->next;
        } 
        if(l2 != NULL){
            //operator on l2
            l2 = l2->next;
        }
    }
    //operator on the remain

    比如LeetCode2的两链表数相加的题:

    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* result = new ListNode(0);
        ListNode* current = result;
        int add = 0;
        while(l1!=NULL || l2!=NULL || add!=0){
            int num1 = 0;
            int num2 = 0;
            if(l1 != NULL){
                num1 = l1->val;
                l1 = l1->next;
            } 
            if(l2 != NULL){
                num2 = l2->val;
                l2 = l2->next;
            }
            ListNode* t = new ListNode((num1+num2+add)%10);
            add = (num1+num2+add)>=10?1:0;
            current->next = t;
            current = t;
        }
        return result->next;
    }                            

    LeetCode2 两数相加:https://leetcode.com/problems/add-two-numbers/description/

    LeetCode21 合并两链表:https://leetcode.com/problems/merge-two-sorted-lists/description/

    LeetCode86 划分链表:https://leetcode.com/problems/partition-list/description/

    LeetCode328 奇偶链表:https://leetcode.com/problems/odd-even-linked-list/description/

    3、前后指针

    l1在前,l2在后,让l2先走n步,当退出第二个循环时,l2位空,l1为倒数第n个节点。可以判断链表是否有环,确定环出现的位置等

    ListNode* l1 = head;
    ListNode* l2 = head;
    while(n-->0){
        l2 = l2->next;
    }
    while(l2 !=NULL){
        l1 = l1->next;
        l2 = l2->next;
    }

    利用快慢指针可以找到链表的中间节点,l1每次向前走一格,l2每次向前走两个。

    当l1、l2都从head开始时,while循环退出时,如果是链表节点数是奇数,则l1指向正中间,如果是偶数,则l1指向位置为中间后一个,例:如果有4个,则l1指向第3个

    ListNode* l1 = head;
    ListNode* l2 = head;
    while (l2 != NULL && l2->next!= NULL) {
        l1 = l1->next;
        l2 = l2->next->next;
    }  

    当l1从head,l2从head->next开始,while循环退出时,如果是链表节点数是奇数,则l1指向正中间,如果是偶数,则l1指向位置为正中间,例:如果有4个,则l1指向第2个

    ListNode* l1 = head;
    ListNode* l2 = head->next;
    while (l2 != NULL && l2->next!= NULL) {
      l1 = l1->next;
      l2 = l2->next->next;
    }

    LeetCode19 移除倒数第n个数:https://leetcode.com/problems/remove-nth-node-from-end-of-list/description/

    LeetCode109 将链表转化为二叉树:https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/description/

    LeetCode141 判断链表是否有环:https://leetcode.com/problems/linked-list-cycle/description/

    LeetCode142 找出链表有环的位置:https://leetcode.com/problems/linked-list-cycle-ii/description/

    LeetCode160 找出两链表的交叉点:https://leetcode.com/problems/intersection-of-two-linked-lists/description/

    287. Find the Duplicate Number https://leetcode.com/problems/find-the-duplicate-number/description/

    数组的快慢指针

    class Solution {
    public:
        int findDuplicate(vector<int>& nums) {
            if(nums.size()<2) return -1;
            int pos1 = nums[0];
            int pos2 = nums[pos1];
            while(pos1!=pos2){
                pos1 = nums[pos1];
                pos2 = nums[nums[pos2]];
            }
            pos1 = 0;
            while(pos1!=pos2){
                pos1 = nums[pos1];
                pos2 = nums[pos2];
            }
            return pos1;
        }
    };
    View Code

    1、数组也会形成环,同160的思路

    4、利用前后指针处理链表内部数据,综合前几种处理方式

    同样是l1和l2指针,一个在前一个在后,只是通过这样遍历一遍需要对链表中的数据进行修改。

    思考方式:

    1、假设进行中间某一点,看需要保存那些位置的值,即考虑n到n+1的情况

    2、查看边界条件,开始位置的边界,结束位置的边界

    反转链表的操作如下,注意将l1初始化为NULL,这样在反转之后可以让尾部节点为空

    ListNode* reverse(ListNode* head){
      if(head == NULL || head->next == NULL) return head;
      ListNode* l1 = NULL;
      ListNode* l2 = head;
      while(l2){
        ListNode* t = l2->next;
        l2->next = l1;
        l1 = l2;
        l2 = t;
      }
      return l1;
    }

     LeetCode24 反转链表中的元素:https://leetcode.com/problems/swap-nodes-in-pairs/description/

     LeetCode61 旋转链表:https://leetcode.com/problems/rotate-list/description/

    LeetCode83 https://leetcode.com/problems/remove-duplicates-from-sorted-list/description/

    LeetCode82 https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/description/

    LeetCode206 颠倒链表:https://leetcode.com/problems/reverse-linked-list/description/

    1、取中间某一个位置,如果需要颠倒链表,需要保存两个值,一个是前面的指针,一个是当前指针,让当前指针的next指向前一个指针,然后两个指针整体向后移动一位,此时由于当前的next被修改了,所以next的位置需要提前被保存起来

    2、考虑边界值,开始时前一个指针需要被设置为NULL,结束时,当前指针为NULL,前一个指针指向最后一个元素。

    LeetCode143 重新整理链表 https://leetcode.com/problems/reorder-list/description/

    是以上几种题型的综合,既有快慢指针,又有反转链表,还有合并链表

    LeetCode234 回文链表 https://leetcode.com/problems/palindrome-linked-list/description/

    LeetCode445 反向相加两数 https://leetcode.com/problems/add-two-numbers-ii/description/

    5、链表排序

    LeetCode 147 链表的插入排序:https://leetcode.com/problems/insertion-sort-list/description/

    LeetCode 148 链表的归并排序:https://leetcode.com/problems/sort-list/description/

    6、其他

    LeetCode 237 删除节点:https://leetcode.com/problems/delete-node-in-a-linked-list/description/

    LeetCode 430 铺展多级链表:https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list/description/

    二、答案以及边界情况

    LeetCode2:

    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* result = new ListNode(0);
            ListNode* current = result;
        int add = 0;
        while(l1!=NULL || l2!=NULL || add!=0){
            int num1 = 0;
            int num2 = 0;
            if(l1 != NULL){
                num1 = l1->val;
                l1 = l1->next;
            } 
            if(l2 != NULL){
                num2 = l2->val;
                l2 = l2->next;
            }
            ListNode* t = new ListNode((num1+num2+add)%10);
            add = (num1+num2+add)>=10?1:0;
            current->next = t;
            current = t;
               }
        return result->next;
    }
    LeetCode2

    1、while循环中未加入add

    2、add的再次计算以及新建ListNode的取值

    3、加入头结点来简化不断增加链表的操作,不加时则需要额外判断第一个节点加入的情况

    LeetCode19:

    View Code

    1、当链表长度为n时会出现删除头节点的情况,加上一个头节点可以简化这种操作

    LeetCode21:

    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
            ListNode l(0);
            ListNode* current = &l;
            while(l1!=NULL&&l2!=NULL){
                if(l1->val < l2->val){
                    current->next = l1;
                    l1 = l1->next;
                }else{
                    current->next = l2;
                    l2 = l2->next;
                }
                current = current->next;
            }
            if(l1 == NULL)
                current->next = l2;
            if(l2 == NULL)
                current->next = l1;
            return l.next;
    }
    LeetCode21

    1、while循环中入股哦是&&,则退出循环需要处理一个为空、一个还有的情况。如果while循环中为||,则在while循环体中需要判断其中一个为空的情况

    LeetCode24:

    ListNode* swapPairs(ListNode* head) {
            if(head == NULL) return head;
            ListNode l1(0);
            l1.next = head;
            ListNode* before = &l1;
            ListNode* t1 = head;
            ListNode* t2 = head->next;
            while(t1!=NULL && t2!=NULL){
                t1->next = t2->next;
                t2->next = t1;
                before->next = t2;
                t1 = t1->next;
                if(t1!=NULL) t2 = t1->next;
                before = before->next->next;
            }
            return l1.next;
        }
    LeetCode24

    1、明白反转链表需要哪几个节点的值再思考

    2、这里需要保存before,但是出现了头节点可能为空的情况

    LeetCode61:旋转链表

    总体思路还是前后指针,但k可能大于链表长度,所以前指针先走的步数不确定

    解法一:前进k步,如果到达链表末尾时还未走k步,则说明k大于链表长度。需要重新从头走k%lenth步。然后前后指针同时向后走,到达末尾后反转。

    ListNode* rotateRight(ListNode* head, int k) {
            if(head == NULL || k == 0) return head;
            int temp = k;
            ListNode t(0);
            t.next = head;
            ListNode* p1 = head;
            ListNode* before1 = &t;
            int num = 0;
            while(p1!=NULL && k-->0){
                num++;
                before1 = before1->next;
                p1 = p1->next;
            }
            if(p1 == NULL){
                k = temp%num;
                if(temp%num == 0) return head;
                p1 = head;
                before1 = &t;
                while(k-->0){
                    before1 = before1->next;
                    p1 = p1->next;
                }
            }
            
            ListNode* p2 = head;
            ListNode* before2 = &t;
            while(p1!=NULL){
                p1 = p1->next;
                p2 = p2->next;
                before1 = before1->next;
                before2 = before2->next;
            }
            before2->next = NULL;
            before1->next = head;
            return p2;
        }
    LeetCode61

    1、如果k==0,也就是最后一步的链表断裂和重新连接的步骤的位置都是同一个,则会形成环,这里需要特别注意(head是绝对位置,before1和before2都是相对位置,当出现这类型赋值时一定要考虑边界条件

    2、head == NULL时,num为0,在除的时候num不能为0,所以开头需要除去head==NULL的情况

    3、在判断k==0时候要注意位置,在对k取余数的时候也会出现余数为0的情况,所以也需要额外的判断k==0

    4、k在循环的时候是不断递减的,需要先保存以下k的值。

    解法二:将链表变成循环链表。相比上一个方法,边界条件少了很多,代码也不容易写错,更加简洁

        ListNode* rotateRight(ListNode* head, int k) {
            if(!head) return head;
            ListNode* p = head;
            int length = 1;
            while(p->next!=NULL){
                p = p->next;
                length++;
            }
            p->next = head;
            for(size_t i = 0;i<length-k%length;i++){
                p = p->next;
            }
            ListNode* result = p->next;
            p->next = NULL;
            return result;
        }
    LeetCode61

    1、注意第一次while循环中的条件

    2、求出链表长度之后,开始遍历的位置是尾部,以及遍历的长度是length-k。这点需要明确。

    LeetCode82:消除重复元素2

    ListNode* deleteDuplicates(ListNode* head) {
            ListNode* p = head;
            ListNode t(0);
            t.next = head;
            ListNode* before = &t;
            while(p!=NULL){
                int num = p->val;
                p = p->next;
                bool change = false;
                while(p!=NULL && p->val == num){
                    change = true;
                    p = p->next;
                }
                if(change){
                    before->next = p;
                }else{
                    before = before->next;
                }
            }
            return t.next;
        }
    LeetCode82

    LeetCode82:消除重复元素

    ListNode* deleteDuplicates(ListNode* head) {
            ListNode* p = head;
            ListNode t(0);
            t.next = head;
            while(p!=NULL){
                int num = p->val;
                ListNode* c = p;
                p = p->next;
                while(p!=NULL && p->val == num){
                    p = p->next;
                }
                c->next = p;
                c = c->next;
            }
            return t.next;
        }
    LeetCode83

    LeetCode86:分割链表

    ListNode* partition(ListNode* head, int x) {
            ListNode t1(0);
            ListNode t2(0);
            ListNode* less = &t1;
            ListNode* bigger = &t2;
            ListNode* current = head;
            while(current!=NULL){
                if(current->val < x){
                    less->next = current;
                    less = less->next;
                }else{
                    bigger->next = current;
                    bigger = bigger->next;
                }
                current = current->next;
            }
            bigger->next = NULL;
            less->next = t2.next;
            return t1.next;
        }
    leetCode86

    1、注意退出while循环后将两个分别的链表拼起来的时候,大于val的链表尾部要设为空。

    LeetCode206:颠倒链表

    ListNode* reverseList(ListNode* head) {
            ListNode* before = NULL;
            while(head){
                ListNode* t = head->next;
                head->next = before;
                before = head;
                head = t;
            }
            return before;
        }
    LeetCode206

    LeetCode206:颠倒链表2

    ListNode t(0);
            t.next = head;
            ListNode* before_m;
            ListNode* _m;
            ListNode* _n;
            ListNode* later_n;
            ListNode* current = head;
            ListNode* before = &t;
            int num = 0;
            while(current){
                num++;
                if(num<m){
                    before = current;
                    current = current->next;
                }else if(num == m){
                    before_m = before;
                    _m = current;
                    ListNode* t = current->next;
                    current->next = NULL;
                    before = current;
                    current = t;
                }else if(num <= n){
                    ListNode* t = current->next;
                    current->next = before;
                    before = current;
                    current = t;
                }else{
                    break;
                }
            }
            _n = before;
            later_n = current;
            
            before_m->next = _n;
            _m->next = later_n;
            return t.next;
    LeetCode92

    完成整个大的目标需要两个条件

    1、翻转m到n的链表

    2、将before_m的next指向n,m的next指向later_n

    然后遍历,在遍历过程中对几个过程进行处理,小于m时,等于m时,大于m小于等于n时

    LeetCode109:将链表转化为二叉树

    TreeNode* sortedListToBST(ListNode* head) {
            if(head == NULL) return NULL;
            if(head->next == NULL){
                TreeNode* result = new TreeNode(head->val);
                return result;
            }
            ListNode* before_l1 = NULL;
            ListNode* l1 = head;
            ListNode* l2 = head->next;
            while(l2!=NULL && l2->next!=NULL){
                before_l1 = l1;
                l1 = l1->next;
                l2 = l2->next->next;
            }
            TreeNode* node = new TreeNode(l1->val);
            if(before_l1 == NULL){
                node->left = sortedListToBST(NULL);
            }else{
                before_l1->next = NULL;
                node->left = sortedListToBST(head);
            }
            node->right = sortedListToBST(l1->next);
            return node;
        }
    LeetCode109

    1、需要注意的是在将链表断成3个部分的时候前一部分有额外情况,那就是链表只有两个节点的时候,l1指向第一个节点,前一部分应该为NULL

    LeetCode138:复制随机链表的指针

    RandomListNode* copyRandomList(RandomListNode *head, map<int, RandomListNode*>& m) {
        if (head == NULL) return NULL;
        if (m.find(head->label) == m.end()) {
            RandomListNode* t = new RandomListNode(head->label);
            m.insert(pair<int, RandomListNode*>(head->label, t));
            t->next = copyRandomList(head->next, m);
            t->random = copyRandomList(head->random, m);
            return t;
        }
        else {
            return (*m.find(head->label)).second;
        }
    }
    RandomListNode *copyRandomList(RandomListNode *head) {
        if (head == NULL) return NULL;
        map<int,RandomListNode*> m;
        return copyRandomList(head,m);
    }
    LeetCode138

    LeetCode141 判断链表是否有环:

    bool hasCycle(ListNode *head) {
            if(head == NULL) return false;
            ListNode t(0);
            t.next = head;
            ListNode* l1 = &t;
            ListNode* l2 = &t;
            while(l2!=NULL && l2->next!=NULL){
                l1 = l1->next;
                l2 = l2->next->next;
                if(l1 == l2) return true;
            }
            return false;
        }
    leetCode141

    1、判断l1等于l2的位置不能写错

    LeetCode142 找出链表有环的位置

    ListNode *detectCycle(ListNode *head) {
            if(!head) return  NULL;
            ListNode t(0);
            t.next = head;
            ListNode* l1 = head;
            ListNode* l2 = head;
            while(l2!=NULL && l2->next!=NULL){
                l1 = l1->next;
                l2 = l2->next->next;
                if(l1 == l2) break;
            }
            if(l2 == NULL || l2->next == NULL) return NULL;
            ListNode* l3 = head;
            while(l1 != l3){
                l1 = l1->next;
                l3 = l3->next;
            }
            return l1;
        }
    LeetCode142

    1、本题链表可能没有环

    LeetCode143 重新整理链表

    void reorderList(ListNode* head) {
            if(head == NULL || head->next == NULL) return ;
            ListNode* l1 = head;
            ListNode* l2 = head->next;
            while(l2 != NULL && l2->next!=NULL){
                l1 = l1->next;
                l2 = l2->next->next;
            }
            ListNode* head2 = l1->next;
            l1->next = NULL;
            l1 = NULL;
            while(head2 != NULL){
                ListNode* t = head2->next;
                head2->next = l1;
                l1 = head2;
                head2 = t;
            }
            //l1是反向链表的头
            ListNode t(0);
            ListNode* result = &t;
            while(l1 != NULL || head!=NULL){
                if(head!=NULL){
                    result->next = head;
                    head = head->next;
                    result = result->next;
                }
                if(l1 != NULL){
                    result->next = l1;
                    l1 = l1->next;
                    result = result->next;
                }
            }
            head = t.next;
            return ;
        }
    LeetCode 143

    LeetCode 147 链表的插入排序

    ListNode* insertionSortList(ListNode* head) {
        ListNode t(INT_MIN);
        t.next = NULL;
        ListNode* l1 = head;
        while (l1 != NULL) {
            //删除l1节点
            ListNode* next = l1->next;
            //从头寻找插入点
            ListNode* before_current = &t;
            ListNode* current = t.next;
            while (current != NULL && current->val<l1->val) {
                before_current = before_current->next;
                current = current->next;
            }
            l1->next = current;
            before_current->next = l1;
    
    
            l1 = next;
        }
        return t.next;
    }
    LeetCode 147

     LeetCode 148 链表的归并排序

    ListNode* merge(ListNode* l1, ListNode* l2) {
        ListNode temp(-1);
        ListNode* result = &temp;
        while (l1 != NULL && l2 != NULL) {
            if (l1->val > l2->val) {
                result->next = l2;
                l2 = l2->next;
            }else {
                result->next = l1;
                l1 = l1->next;
            }
            result = result->next;
        }
        if (l1 == NULL)
            result->next = l2;
        else
            result->next = l1;
        return temp.next;
    }
    ListNode* sortList(ListNode* head) {
        if (head == NULL || head->next == NULL) return head;
        ListNode* l1 = head;
        ListNode* l2 = head->next;
        while (l2 != NULL && l2->next!= NULL) {
            l1 = l1->next;
            l2 = l2->next->next;
        }
        //l1是中间节点
        l2 = l1->next;
        l1->next = NULL;
    
        return merge(sortList(head), sortList(l2));
    }
    LeetCode 148

    LeetCode160 找出两链表的交叉点

    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
            int lengthA = 0;
            ListNode* l = headA;
            while(l!=NULL){
                lengthA++;
                l = l->next;
            }
            int lengthB = 0;
            l = headB;
            while(l!=NULL){
                lengthB++;
                l = l->next;
            }
            ListNode* l1 = headA;
            ListNode* l2 = headB;
            if(lengthA<lengthB){
                int t = lengthB-lengthA;
                for(size_t i =0;i<t;i++)
                    l2 = l2->next;
            }else{
                int t = lengthA-lengthB;
                for(size_t i =0;i<t;i++)
                    l1 = l1->next;
            }
            while(l1 != l2){
                l1 = l1->next;
                l2 = l2->next;
            }
            return l1;
        }
    LeetCode 160

    LeetCode 203 删除节点中的元素

    ListNode* removeElements(ListNode* head, int val) {
            if (head == NULL ) return NULL;
            ListNode* l = head;
            ListNode t(-1);
            t.next = head;
            ListNode* l_before = &t;
            while (l) {
                if (l->val == val)
                    l_before->next = l->next;
                else
                    l_before = l;
                l = l->next;
            }
            return t.next;
        }
    LeetCode203

    LeetCode234 回文链表

    bool isPalindrome(ListNode* head) {
            if(head == NULL || head->next == NULL) return true;
            ListNode* l1 = head;
            ListNode* l2 = head->next;
            while(l2!=NULL && l2->next!=NULL){
                l1 = l1->next;
                l2 = l2->next->next;
            }
            l2 = l1->next;
            l1->next = NULL;
            l1 = NULL;
            while(l2 != NULL){
                ListNode* t = l2->next;
                l2->next = l1;
                l1 = l2;
                l2 = t;
            }
            //l1是后一部分的头
            while(l1!=NULL && head!=NULL){
                if(l1->val != head->val) return false;
                l1 = l1->next;
                head = head->next;
            }
            return true;
        }
    LeetCode 234

    1、注意就情况的区分

    LeetCode 237 删除节点

    void deleteNode(ListNode* node) {
            if (!node || !node->next)
                return;
            node->val = node->next->val;
            node->next = node->next->next;
        }
    LeetCode237

    LeetCode328 奇偶链表

    ListNode* oddEvenList(ListNode* head) {
            if(head == NULL || head->next == NULL) return head;
            ListNode* head1 = head,*current1 = head;
            ListNode* head2 = head->next,*current2 = head->next;
            ListNode* current = head->next->next;
            while(current != NULL){
                current1->next = current;
                current1 = current1->next;
                current = current->next;
                if(current != NULL){
                    current2->next = current;
                    current2 = current2->next;
                    current = current->next;
                }
            }
            current1->next = head2;
            current2->next = NULL;
            return head1;
        }
    LeetCode 328

    LeetCode445 反向相加两数

    ListNode* reverse(ListNode* head){
            if(head == NULL || head->next == NULL) return head;
            ListNode* l1 = NULL;
            ListNode* l2 = head;
            while(l2){
                ListNode* t = l2->next;
                l2->next = l1;
                l1 = l2;
                l2 = t;
            }
            return l1;
        }
        ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
            ListNode* new1 = reverse(l1);
            ListNode* new2 = reverse(l2);
            //加两个链表,前面有一个题和这里一模一样
            int add = 0;
            ListNode* current1 = new1;
            ListNode* current2 = new2;
            ListNode result(0);
            ListNode* current = &result;
            while(current1 || current2 || add==1){
                int num1 = 0;
                int num2 = 0;
                if(current1){
                    num1 = current1->val;
                    current1 = current1->next;
                } 
                if(current2) {
                    num2 = current2->val;
                    current2 = current2->next;
                }
                current->next = new ListNode((num1+num2+add)%10);
                add = (num1+num2+add)/10;
                current = current->next;
            }
            
            return reverse(result.next);
        }
    LeetCode 445

    LeetCode 430 铺展多级链表

    Node* flatten(Node* head) {
            if(head == NULL || (head->child == NULL && head->next == NULL)) return head;
            if(head->child == NULL ) {
                head->next = flatten(head->next);
                head->next->prev = head;
                return head;
            }else if(head->next == NULL){
                head->next = flatten(head->child);
                head->next->prev = head;
                head->child = NULL;
                return head;
            }else{
                Node* n = flatten(head->next);
                Node* c = flatten(head->child);
                head->next = c;
                c->prev = head;
                Node* t = head;
                while(c->next!=NULL){
                    c = c->next;
                }
                c->next = n;
                n->prev = c;
                head->child = NULL;
                return head;
            }
        }
    LeetCode 430

    这题和链表相关不大,会递归或是迭代的写法都可以。

    三、复习题目

    61

    109

    141

    143

    147

    148

    287

  • 相关阅读:
    BZOJ 4815: [Cqoi2017]小Q的表格
    BZOJ 3676: [Apio2014]回文串
    BZOJ 4503: 两个串
    BZOJ 2618: [Cqoi2006]凸多边形
    BZOJ 1137: [POI2009]Wsp 岛屿
    BZOJ 4824: [Cqoi2017]老C的键盘
    BZOJ 3167: [Heoi2013]Sao
    BZOJ 4033: [HAOI2015]树上染色
    1003. 我要通过!(20)
    1002. 写出这个数 (20)
  • 原文地址:https://www.cnblogs.com/likaiming/p/9398548.html
Copyright © 2011-2022 走看看