25-k个一组翻转链表 203-移除链表元素 206-反转一个链表

题目:

给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。

k 是一个正整数,它的值小于或等于链表的长度。

如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

 

示例:

  给你这个链表:1->2->3->4->5

  当 k = 2 时,应当返回: 2->1->4->3->5

  当 k = 3 时,应当返回: 3->2->1->4->5

 

说明:

  你的算法只能使用常数的额外空间。
  你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

解答:看懂了,但是自己写有问题,自己写的太多的判断了,直接看解答

//指定head,然后在k段内翻转,k段内都不为nullptr
//head-开始的头结点
//tail-要翻转的最后一个节点
//返回:翻转后的头-尾节点
pair<ListNode*, ListNode*> reverseK(ListNode* head, ListNode* tail)
{
    ListNode* pre = tail->next;//使用尾部的下一个元素作为头
    ListNode* cur = head;
    ListNode* next = nullptr;
    while (pre != tail)
    {
        next = cur->next;
        cur->next = pre;
        pre = cur;
        cur = next;
    }

    return{ tail, head };
}
ListNode* reverseKGroup(ListNode* head, int k) 
{
    ListNode* dummy = new ListNode(0);
    dummy->next = head;
    ListNode* pre = dummy;

    while (head != nullptr)
    {
        ListNode* tail = pre;
        for (int i = 0; i < k; i++)
        {
            tail = tail->next;
            if (tail == nullptr)//如果链表长度小于k,则直接返回该链表
                return dummy->next;
        }

        ListNode* next = tail->next;//k段链表的下一个节点
        pair<ListNode*, ListNode*> result = reverseK(head, tail);

        head = result.first;
        tail = result.second;

        //把k段的链表重新接回原链表
        pre->next = head;
        tail->next = next;

        //更新pre head,用于下一段k的反转;
        pre = tail;
        head = tail->next;
    }

    return dummy->next;
}

 

 

相关题目:

203-移除链表元素

206-反转一个链表

题目-206

反转一个单链表。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
  你可以迭代或递归地反转链表。你能否用两种方法解决这道题?

解答:

代码一:迭代方法:

if (head == nullptr)
        return head;
    if (head->next == nullptr)//如果链表就一个节点,则直接返回
        return head;

    ListNode* pre = nullptr;
    ListNode* cur = head;
    ListNode* next = nullptr;
    while (cur != nullptr)
    {
        next = cur->next;
        cur->next = pre;
        pre = cur;
        cur = next;
    }

    return pre;
}

方法二:递归:https://leetcode-cn.com/problems/reverse-linked-list/solution/fan-zhuan-lian-biao-by-leetcode/

题目-203

删除链表中等于给定值 val 的所有节点。

示例:

输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5

解答:

自己写的代码:

//链表中可能有多个符合的元素
ListNode* removeElements(ListNode* head, int val) 
{
    if (head == nullptr)
        return head;
    while (head!= nullptr && head->val == val)
        head = head->next;

    ListNode dummy;
    dummy.next = head;
    ListNode* tmp = &dummy;
    ListNode* pre = &dummy;
    while (tmp != nullptr)
    {
        tmp = tmp->next;
        while (tmp != nullptr && tmp->val == val)
        {
            tmp = tmp->next;
        }

        pre->next = tmp;
        pre = tmp;
    }

    return head;
}

问题:上面的代码没有释放移除节点,需要delete,修改如下:

//上面的函数没有删除移除的节点,
ListNode* removeElements2(ListNode* head, int val)
{
    if (head == nullptr)
        return head;
    ListNode* toBeDelete = nullptr;
    while (head != nullptr && head->val == val)
    {
        toBeDelete = head;
        head = head->next;
        if (toBeDelete != nullptr)
            delete toBeDelete;
    }

    ListNode dummy;
    dummy.next = head;
    ListNode* tmp = &dummy;
    ListNode* pre = &dummy;
    while (tmp != nullptr)
    {
        tmp = tmp->next;
        while (tmp != nullptr && tmp->val == val)
        {
            toBeDelete = tmp;
            tmp = tmp->next;

            if (toBeDelete != nullptr)
                delete toBeDelete;
        }

        pre->next = tmp;
        pre = tmp;
    }

    return head;
}

解答中的代码很简洁,如下,使用了一个哨兵sentinel,而且根据当前的cur的val是否为目标值对pre进行不同的处理,逻辑比自己写的简单:

ListNode* removeElements3(ListNode* head, int val)
{
    ListNode* sentinel = new ListNode(0);
    sentinel->next = head;

    ListNode* pre = sentinel;
    ListNode* cur = head;
    ListNode* toBeDelete = nullptr;

    while (cur != nullptr)
    {
        if (cur->val == val)
        {
            pre->next = cur->next;
            toBeDelete = cur;
        }
        else
            pre = cur;

        cur = cur->next;

        if (toBeDelete != nullptr)
        {
            delete toBeDelete;
            toBeDelete = nullptr;
        }
    }

    ListNode* ret = sentinel->next;
    delete sentinel;
    return ret;
}

 

posted @ 2020-11-18 15:02  adfas  阅读(97)  评论(0编辑  收藏  举报