删除链表节点&&反转链表II

举报
芒果_Mango 发表于 2022/11/30 23:49:53 2022/11/30
【摘要】 237. 删除链表中的节点https://leetcode.cn/problems/delete-node-in-a-linked-list/方法:记node的下一个节点尾next 要删除node1.可以把next的数据搬到node,2.然后释放next节点,让node链接其下一个节点由于题目已经说了,node不是尾节点,所以node->next->next不会非法访问!class Sol...

237. 删除链表中的节点

https://leetcode.cn/problems/delete-node-in-a-linked-list/

方法:
记node的下一个节点尾next 要删除node

1.可以把next的数据搬到node,
2.然后释放next节点,让node链接其下一个节点

image-20220526151008096

由于题目已经说了,node不是尾节点,所以node->next->next不会非法访问!

class Solution {
public:
    //题目数据保证需要删除的节点 不是末尾节点
    //无法访问链表的头节点 head ,只能直接访问 要被删除的节点
    void deleteNode(ListNode* node) {
        //node next 要删除node =>可以把next的数据搬到node,然后释放next节点,让node链接其下一个节点
        ListNode* next = node->next;
        node->val = next->val;
        node->next = next->next;
        delete next;
    }
};

19. 删除链表的倒数第 N 个结点

https://leetcode.cn/problems/remove-nth-node-from-end-of-list/

image-20220524083618652

思路:快慢指针,因为要删除倒数第N个节点,删除前我们要进行前后节点的链接,所以还要多定义一个指针

/**
 * 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* removeNthFromEnd(ListNode* head, int n) {
        if(head==nullptr || n<0)
        {
            return head;
        }
        //快慢指针,二者从头开始
        ListNode* pre = nullptr;
        ListNode* fast = head;
        ListNode* slow = head;
        //快指针先走n步
        //while(n--) ->走n步  while(--n)->走n-1步
        while(n--)
        {
            if(!fast) return nullptr;//如果提前走到空,说明没有倒数第n个节点 -> n>链表长度
            fast = fast->next;
        }
        //fast和slow一起走,注意前驱指针也要一起走!删除之后要进行链接
        while(fast)
        {
            fast = fast->next;
            pre = slow;//前驱指针跟在slow后面
            slow = slow->next;
        }
        //判断删除的是否是头节点
        if(slow == head)
        {
            head = head->next;//换头
        }
        else
        {
            pre->next = slow->next;//pre slow slow->next  slow就是要删除的节点
        }
        delete slow;
        return head;
    }
};

92. 反转链表 II

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

头插法

我们最好使用哨兵位节点!防止头节点就是要反转的第一个节点!

由实例中可以得知:这里的节点编号从1开始,即头节点是第一个节点

反转的时候需要知道前一个节点的位置,所以需要双指针同时移动,pre跟在cur的后面, 然后pre cur cur->next三者进行重新链接 类似于头插

如图:类似于牛客的题目

image-20220526103607356

cur:指向待反转区域的第一个节点left
next(temp):永远指向 cur 的下一个节点,循环过程中,cur 变化以后 next 会变化
pre:永远指向待反转区域的第一个节点 left 的前一个节点,在循环过程中不变
/**
 * 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* reverseBetween(ListNode* head, int left, int right) {
        //链表为空直接返回,不需要反转
        if(head == nullptr)
        {
            return head;
        }
        //因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论
        ListNode* pHead = new ListNode(-1);//哨兵位节点
        pHead->next = head;//哨兵位连接原链表
        ListNode* pre = pHead;
        ListNode* cur = head;
        //头节点是第一个节点,所以从1开始,而不是从0开始
        //先来到第left个节点的位置
        for(int i = 1;i<left;i++)
        {
            pre = cur;
            cur = cur->next;
        }
        //此时cur就是第left个节点, pre就是其前一个节点
        for(int i = left;i<right;i++)
        {
            ListNode* temp = cur->next;
            //pre cur next(temp)进行链接反转
            cur->next = temp->next;
            temp->next = pre->next;
            pre->next = temp;
        }
        return pHead->next;
    }
};

image-20220526103644761

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。