链表翻转

链表翻转

题目要求:翻转链表中某一段的节点

思路:建立一个新节点dummy,新节点的next节点指向原来的头节点,这样就算原来的头节点变动了,我们还可以使用dummy->next来获得新链表的头节点

建立一个指针pre,pre节点始终指向要翻转的那段链表的前驱节点,然后令cur=pre->next始终指向下一个要翻转的节点,然后cur不断向后移动,每次将cur->next指向的节点插入到pre节点后,这样链表就完成了翻转。

//比如1->2->3->4->5,m=1,n=5
//第一次反转:(pre)1(cur) 2(next) 3 4 5 反转为 2 1 3 4 5
//第二次反转:(pre)2 1(cur) 3(next) 4 5 反转为 3 2 1 4 5
//第三次发转:(pre)3 2 1(cur) 4(next) 5 反转为 4 3 2 1 5
//第四次反转:(pre)4 3 2 1(cur) 5(next) 反转为 5 4 3 2 1

例题:

1.反转链表

https://leetcode-cn.com/problems/reverse-linked-list/

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode * dummy = new ListNode(-1);
        dummy->next = head;
        ListNode* pre = dummy;
        ListNode* cur = pre->next;
        while(cur!=nullptr && cur->next != nullptr){
            ListNode * nxt = cur->next;
            cur->next = nxt->next;
            nxt->next = pre->next;
            pre->next = nxt;
        }
        return dummy->next;
    }
};

2.反转链表 II

https://leetcode-cn.com/problems/reverse-linked-list-ii/

思路:这个虽然是要求翻转某一段链表,但思路跟上题是一样的

class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        ListNode * dummy = new ListNode(-1);
        ListNode * pre = dummy;
        dummy->next = head;
        for(int i=1;i<m;i++) pre = pre->next;
        head = pre->next; //我这里是直接对head指针进行操作的,没有使用新指针cur
        // cout<<head->val<<endl; 
        for(int i=m;i<n;i++){
            ListNode * nxt = head->next;
            head->next =  nxt->next;
            nxt->next = pre->next;
            pre->next = nxt;
        }
        return dummy->next;
    }
};

3.K 个一组翻转链表

https://leetcode-cn.com/problems/reverse-nodes-in-k-group/

思路:先求出链表的大小,得到有几组链表需要翻转,然后跟上题一样,cur指针指向要翻转的节点,pre指针指向该段链表的前驱节点。


class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode * dummy = new ListNode(-1);
        ListNode * pre = dummy;
        dummy->next = head;
        int size = 0;
        while(head != nullptr){
            head = head->next;
            size++;
        }
        head = pre->next; //我这里是直接对head指针进行操作的,没有使用新指针cur
        for(int i=1;i<=size/k;i++){
            for(int i=1;i<k;i++){
                ListNode* nxt = head->next;
                head->next = nxt->next;
                nxt->next = pre->next;
                pre->next = nxt;
            }
            head=head->next;
            for(int i=1;i<=k;i++){
                pre = pre->next;
            }
            cout<<pre->val<<endl;
        }
        return dummy->next;
    }
};
七月在野,八月在宇,九月在户,十月蟋蟀入我床下
原文地址:https://www.cnblogs.com/voids5/p/14377738.html