链表LeetCode练习

链表LeetCode练习

反转链表

class Solution {
public:
    ListNode* reverseList(ListNode* head)
    {
        if (head == NULL || head->next == NULL) return head;
        ListNode* t1, *t2,*t;
        t1 = head;
        t2 = head->next;
        t1->next = NULL;
        while (t2)
        {
            t = t2->next;
            t2->next = t1;
            t1 = t2;
            t2 = t;
        }
        return t1;
    }
};

两两交换链表中的节点

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode **pp = &head, *a, *b;
        while ( (a = *pp) && (b = a->next)){
            a->next = b->next;
            b->next = a;
            *pp = b;
            pp = &(a->next);
        }
        return head;

    }
};

环形链表

class Solution {
public:
    bool hasCycle(ListNode *head) {
        //特判链表结点为空的情况
        if(!head) return false;
        ListNode* slow = head;
        ListNode* fast = head;
        while(fast->next && fast->next->next) {
            //必须让快指针先跑
            fast = fast->next->next;
            if(slow == fast) return true;
            else slow = slow->next;
        }
        return false;
    }
};

环形链表 II

class Solution {
public:
    ListNode* detectCycle(ListNode* head) {
    ListNode* fastPtr=head, *slowPtr=head;
    // 让fast与slow指针第一次相遇
    while (fastPtr!=NULL && fastPtr->next!=NULL)
    {
        fastPtr = fastPtr->next->next;
        slowPtr = slowPtr->next;
        if (fastPtr==slowPtr)
        {
            // 从相遇点再走“非环部分长度”一定可以再次走到环起点
            fastPtr = head;
            while (fastPtr != slowPtr)
            {
                fastPtr = fastPtr->next;
                slowPtr = slowPtr->next;
            }
            return fastPtr;
            break;
        }
    }

    return nullptr;
}
};

K 个一组翻转链表

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        //特殊情况:NULL或仅有一个节点
        if(head == nullptr || head->next == nullptr)
            return head;

        //虚拟头结点
        ListNode *dummyHead = new ListNode(0);
        dummyHead->next = head;

        //next指向当前结点的下一个结点
        ListNode *next = head;
        //pre_tail指向上一段链表的尾节点,初始值为空指针
        ListNode *pre_tail = nullptr;
        //每一个段的头结点
        ListNode *newHead = head;
        //计数值,当count增加到k时,就断链,倒置,挂链
        int count = 0;

        while(head){
            count++;
            next = head->next;
            if(count == k){
                //断链,并且将该小段链表送入倒置函数中
                head->next = nullptr;
                HeadTail headTail = reverse(newHead);

                //挂链:处理倒置后的链表的头和尾,巧妙利用pre初始值是否为空
                if(pre_tail)
                    //不为空,则上一段链表尾节点指向新置链表头结点
                    pre_tail->next = headTail.head;
                else
                    //为空,则虚拟头结点指向新置链表头结点
                    dummyHead->next = headTail.head;

                headTail.tail->next = next;

                //更新上一段链表的尾节点、下一段链表的头结点和计数值count
                pre_tail = headTail.tail;
                newHead = next;
                count = 0;//别忘记计数值重置
            }
            
            head = next;
        }
        return dummyHead->next;//dummyHead大法好
    }

    //链表的头和尾结构体
    struct HeadTail{
        ListNode *head;
        ListNode *tail;
    };

    //reverse函数返回两个参数:倒置后的链表头和尾
    HeadTail reverse(ListNode* head){
        //巧妙使用pre指针,初始值为空
        ListNode *pre = nullptr;
        ListNode *cur = head;
        ListNode *next = head;
        while(cur){
            next = cur->next;
            //pre初始值为空
            cur->next = pre;
            //更新pre值,很巧妙
            pre = cur;
            cur = next;
        }
        HeadTail headTail;
        headTail.head = pre;
        headTail.tail = head;

        return headTail;
    }
};

猜你喜欢

转载自www.cnblogs.com/liugangjiayou/p/12389549.html