删除链表的倒数第 n 个结点,删除排序链表中的重复元素 II
一 删除链表的倒数第 n 个结点
题目链接:. - 力扣(LeetCode)
给定一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例:
输入:head = [1,2,3,4,5],n = 2
输出:[1,2,3,5]
解题思想:
找到倒数第n个节点,可以使用快慢指针同时对链表进行遍历,并且fast比slow超前n个节点。当fast遍历到链表的末尾时,slow就恰好处于倒数第n个节点。
首先fast和slow都指向头节点。fast指针先向前走n步。此时,fast和slow之间间隔了n-1个节点,即fast比slow超前了n个节点。
之后用两个指针同时对链表进行遍历。当fast遍历到链表的末尾时,slow恰好指向倒数第n个节点。
代码:
class Solution {
public:ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode*fast=head;ListNode*slow=head;for(int i=0;i<n;i++){fast=fast->next;}if(fast==NULL) return head->next;while(fast->next){slow=slow->next;fast=fast->next;}slow->next=slow->next->next;return head;}
};
二 删除排序链表中的重复元素 II
题目链接:力扣:82.删除排序链表中的重复元素Ⅱ
给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
示例:
输入:head = [1,2,3,3,4,4,5]
输出:[1,2,5]
解题思想:
本题是要将链表中的重复元素全部删除。可以使用双指针的思想,que用于记录当前不重复的节点,cur用于遍历整个链表。通过比较当前节点和下一个节点的值,可以确定是否需要将当前节点添加到结果链表中。
具体讲,使用Head作为链表的虚头节点,que初始化为哨兵节点,cur初始化为链表的头节点。
在遍历链表时,将cur与它下一个节点进行比较。如果他们的值相同,说明存在重复节点,所以需要继续寻找第一个不同的节点。当找到不同的节点时(即cur节点的值与下一个节点不等时),我们将当前节点加入到结果链表,并将que指针指向这个新节点。
最后,处理链表末尾的情况。如果最后一个结点和前面的节点都相同,那么需将que指针和next指针置为nullptr,以确保链表截断只包含不重复节点的部分。
代码:
class Solution {
public:ListNode* deleteDuplicates(ListNode* head) {if (head == nullptr) {return head;}ListNode* Head = new ListNode(0); Head->next = head;ListNode* que = Head; ListNode* cur = head; while (cur != nullptr && cur->next != nullptr) {if (cur->val != cur->next->val) {if (que->next == cur) {que = cur;} else {que->next = cur->next;}}cur = cur->next;}if (que->next != cur) {que->next = nullptr;}ListNode* ans = Head->next;delete Head;return ans;}
};
祝大家生活愉快。