【链表】反转链表, 链表的交换, k 个 一组翻转链表

反转链表示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

思路

  • 备份 旧head->next
  • head->next更新为新节点
  • head 变为 旧head->next
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* p = nullptr;
        while(head){
            ListNode* tmp = head->next;//旧head->next备份
            head->next = p;//新 head->next
            p = head;//p更新
            head = tmp;//head 变为 旧head->next
        }
        return p;
    }
};

链表交换示例

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

给定 1->2->3->4, 你应该返回 2->1->4->3.
  • 和反转链表思路相同,也是从头节点遍历,交换链表顺序
  • 不同的是,这一题要交换两个链表,会有两个临时变量,进行三次操作
  • 这三次操作分别是:
    图片来自leetcode
  • 注意:node2的next更新一定是要在node1的next更新之后,否则node2->next=node1, node1->next=node2, 这样就成了环,从而进入死循环
  • 注意:交换的是head->next 和 head->next->next, 那head咋办?为了要让head能成为一个节点的next,所以定义一个头节点,该节点的next指向head
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* first = new ListNode(0);
        first->next = head;
        ListNode* p = first;
        while(p->next && p->next->next){
            ListNode* tmp1 = p->next;
            ListNode* tmp2 = p->next->next;

            p->next = tmp2;
            tmp1->next = tmp2->next;
            tmp2->next = tmp1;

            p = tmp1;
        }
        return first->next;
    }
};

k 个一组反转链表

25. K 个一组翻转链表

  • 上边相当于2个一组翻转链表
  • k 个一组的话相当于先每k个切一刀,把这段翻转(子链表反转),再接回原处
class Solution {
public:
    //翻转某一段
    pair<ListNode*, ListNode*> reverse(ListNode* head, ListNode* tail){
        ListNode* p = tail->next;
        ListNode* head_tmp = head;
        while(p != tail){
            ListNode* tmp = head->next;
            head->next = p;
            p = head;
            head = tmp;
        }
        return {p, head_tmp};
    }

    ListNode* reverseKGroup(ListNode* head, int k) {
        if(!head) return nullptr;
        //
        ListNode hair(0);
        hair.next = head;
        ListNode* pre = &hair;

        while(head){
            ListNode* tail = pre;
            for(int i = 0; i < k; ++i){
                tail = tail->next;
                if(!tail){
                    return hair.next;//不足k个,保持原有顺序
                }
            }
            //备份
            ListNode* tmp = tail->next;
            //翻转
            auto ll = reverse(head, tail);
            head = ll.first;
            tail = ll.second;
            //接回来
            pre->next = head;
            tail->next = tmp;
            //pre、tail移动
            pre = tail;
            head = tail->next;
        }
        return hair.next;
    }
};
posted @ 2020-10-11 20:09  miyanyan  阅读(171)  评论(0编辑  收藏  举报