0
点赞
收藏
分享

微信扫一扫

c++数据结构(2)——链表

两岁时就很帅 2022-01-17 阅读 68

反转链表,技巧也是dummy节点、双指针

206. 反转链表(简单)

92. 反转链表II(中等)

25. K个一组翻转链表(困难)

234. 回文链表(简单)

完全反转链表,记住这个,这是所有反转链表的基础

/**
 * 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 *pre = nullptr;
        ListNode *cur = head;
        while (cur) {
            ListNode *next = cur->next;
            cur->next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
};

部分反转链表,在反转链表的基础上增加了找左右边界,以及边界截断与连接

/**
 * 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 *pre = nullptr;
        ListNode *cur = head;
        while (cur) {
            ListNode *next = cur->next;
            cur->next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
    ListNode* reverseBetween(ListNode* head, int left, int right) {
        ListNode dummy;
        dummy.next = head;
        //找出左右边界
        ListNode *pre = &dummy;
        for (int i = 0; i < left-1; i++) {
            pre = pre->next;
            if (pre == nullptr) return head;
        }
        ListNode *leftNode = pre->next;
        ListNode *rightNode = pre;
        for (int i = 0; i < right - left + 1; i++) {
            rightNode = rightNode->next;
            if (rightNode == nullptr) break;
        }
        //保存左右外边界
        ListNode *cur = rightNode->next;
        //截断
        pre->next = nullptr;
        rightNode->next = nullptr;
        //翻转
        reverselist(leftNode);

        //连接
        pre->next = rightNode;
        leftNode->next = cur;

        return dummy.next;
    }
};

k个一组翻转链表,跟上面的一样,增加边界处理

/**
 * 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:
    void reverselist(ListNode *head)
    {
        ListNode *pre = nullptr;
        ListNode *cur = head;
        while (cur) {
            ListNode *next = cur->next;
            cur->next = pre;
            pre = cur;
            cur = next;
        }
    }
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode dummy;
        dummy.next = head;
        ListNode *pre = &dummy;
        while (pre) {
            ListNode *left = pre->next;
            ListNode *right = pre;
            for (int i = 0; i < k; i++) {
                right = right->next;
                if (right == nullptr) return dummy.next;
            }
            //截断
            ListNode *cur = right->next;
            pre->next = nullptr;
            right->next = nullptr;
            //翻转
            reverselist(left);
            //接上
            pre->next = right;
            left->next = cur;

            //下一个
            pre = left;
        }
        return dummy.next;
    }
};

234. 回文链表(简单)

只写进阶解法,额外增加了双指针找中点

/**
 * 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* reverse(ListNode *head)
    {
        ListNode *pre = nullptr;
        ListNode *cur = head;
        while (cur) {
            ListNode *next = cur->next;
            cur->next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
    bool isPalindrome(ListNode* head) {
        //快慢指针找到中点
        ListNode *s, *f;
        s = f = head;
        while (f && f->next) {
            f = f->next->next;
            s = s->next;
        }
        //奇数时,只反转后半段
        if (f) s = s->next;
        ListNode* right = reverse(s);
        ListNode* left = head;
        while (right) {
            if (right->val != left->val) return false;
            right = right->next;
            left = left->next;
        }
        return true;
    }
};
举报

相关推荐

0 条评论