24. 两两交换链表中的节点

24. 两两交换链表中的节点

24. 两两交换链表中的节点_第1张图片

这道题乍一看,这有啥难度 就是把反转链表变成两个两个反转

思路没有错的 解决的问题分别是:

1 如何反转链表

2 如何按照指定长度反转链表

我们一个一个来看,首先是如何反转链表,绝大多数人首先想到的一定是使用一个前置指针prev进行反转。例如下面所示:

ListNode * reverseListNode(ListNode * head){
    if(head == nullptr) return nullptr;
    if(head->next == nullptr) return head;
    ListNode * prevNode  = nullptr;
    ListNode * currentNode = head;
    while(currentNode!=nullptr){
        ListNode * tmpNode = currentNode->next;
        currentNode->next = prevNode;
        prevNode = currentNode;
        currentNode = tmpNode;
    }
    return prevNode;
}

之后是何如K个一组反转链表呢?同leetcode25题。

首先也需要有一个反转链表的函数,我们对上面的函数做一个小小改动添加一个lastNode的参数

//反转位置是head到last-1的链表
ListNode * reverseListNode(ListNode * head, ListNode * last){
    if(head == nullptr) return nullptr;
    if(head->next == nullptr) return head;
    ListNode * currentNode = head;
    ListNode * prevNode = nullptr;
    while(currentNode != last){
        auto tmpNode = currentNode->next;
        currentNode->next = prevNode;
        prevNode = currentNode;
        currentNode = tmpNode;
    }
    return prevNode;
}

ListNode * reverseGroup(ListNode * head, int k){
    ListNode * last = head;
    //注意这里实际上last已经移动到了[k]
    for(auto i = 0; i < k; i++){
        if(last != nullptr){
            last = last->next;
        }else{
            return head;
        }
    }
    auto lastNode = reverse(head, last);
    head->next = reverseGroup(last, k);
    return lastNode;
}

其实这里还有一个问题,如果链表中最后一组不满k个数,可以分为两种输出结果,一种是继续反转剩余不满k个的那组,一个是剩余不满的那组不反转。这里题目中是不反转,如果改为需要反转,可以直接修改为:

    for(auto i = 0; i < k; i++){
        if(last != nullptr){
            last = last->next;
        }else{
            return head;
        }
    }
=======================================
    for(auto i = 0; i < k; i++){
        if(last != nullptr){
            last = last->next;
        }else{
        //注意修改这里
            return reverse(head,last);
        }
    }

这是面试官最喜欢问的一个变种。

回到最初的问题,两个两个交换是不是就是直接把k设置为2.

当然这里有一个更简单的解法,利用递归的方式:

ListNode* swapPairs(ListNode* head) {
    if(head == nullptr) return nullptr;
    if(head->next == nullptr) return head;
    ListNode* newhead = head->next;
    //这里递归
    head->next =  swapPairs(newhead->next);
    newhead->next = head; 
    return newhead;
}

这种递归的方式是不是会有栈溢出的风险呢?

你可能感兴趣的:(src,leetcode)