LeetCode 206/24/25:一系列链表翻转问题

206. 翻转链表: 

加头结点,没有必要: 

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(!head) return nullptr;

        ListNode dummy(0);
        dummy.next = head;
        ListNode *prev = &dummy, *curr = head, *next = head;
        while(curr) {
            next = curr->next;
            curr->next = prev;
            prev = curr;
            curr = next;
        }
        head->next = nullptr;
        head = prev;
        return head;
    }
};

不加头结点更简洁: 

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(!head) return nullptr;

        ListNode *prev = nullptr, *curr = head, *next = head;
        while(curr) {
            next = curr->next;
            curr->next = prev;
            prev = curr;
            curr = next;
        }
        return prev;
    }
};

24. 两两一组翻转链表

自己在纸上画出链表连接变化图,按照图上的逻辑对指针操作。开始的连接关系画成了“1->3”,实际应该是“1->4”导致部分节点被漏掉。修改逻辑错误之后又出现了两处Bug:均为考虑temp及temp->next不够具体,混为一谈导致的。最终通过的代码:

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(!head || !head->next) return head;

        ListNode *pFirst = head, *pSecond = head->next, *pRet = pSecond, *temp;
        while(pFirst && pSecond) {
            temp = pSecond->next;
            pSecond->next = pFirst;
            if(temp && temp->next) {    //Bug2:想了很久才搞清楚的Bug,会陷入死循环超时,完善if的条件,再加上else处理,即可
                pFirst->next = temp->next;
            }
            else{
                pFirst->next = temp;
            }
            pFirst = temp;
            if(temp) pSecond = temp->next; //Bug1: 没有判断temp是否为null直接进行->next
        }

        return pRet;
    }
};

参考官方迭代解法,迭代思路更简洁,prev作为已反转的序列的最后一个节点,将他的后两个节点翻转,用python写的,熟悉一下Python刷题。 

class Solution:
    def swapPairs(self, head: ListNode) -> ListNode:
        if not head or not head.next:
            return head
        
        dummy = ListNode(-1)
        dummy.next = head

        prev = dummy
        first = head

        while first and first.next:
            second = first.next
            ##Swap
            prev.next = second
            first.next = second.next
            second.next = first
            ##Reinitialization
            prev = first
            first = first.next
        
        return dummy.next

 递归的解法,每次递归将两个节点翻转。

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(!head || !head->next) return head;

        ListNode *pFirst = head->next;
        head->next = swapPairs(head->next->next);
        pFirst->next = head;

        return pFirst;
    }
};

25. K个一组翻转链表

借鉴了24题中的递归解法的思路,比较快比较顺利的完成了这道题:还是递归进行翻转,先调用到最末尾,从最后一段逐次向前一段一段进行翻转。

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode* rear = head;
        for(int i = 0; i<k; i++) {
            if(rear) {
                rear = rear->next;
            }
            else {
                return head;
            }
        }
        ListNode *prev = reverseKGroup(rear, k);
        //ListNode* prev = rear, *curr = head, *next = head;
        ListNode *curr = head, *next = head;
        for(int i = 0; i<k; i++) {
            next = curr->next;
            curr->next = prev;
            prev = curr;
            curr = next;
        }
        return prev;
    }
};
发布了97 篇原创文章 · 获赞 11 · 访问量 2477

猜你喜欢

转载自blog.csdn.net/chengda321/article/details/104116165