删除倒数第k个节点
但是这道题head指向的是第一个有效节点,没有头节点了,所以我们要注意哦
我们采用双指针思想。定义p和q指针,指向头节点,然后p先走k个节点,然后p和q一起向后走,直到q走到尾节点处
此时q访问的是倒数第k+1个节点
然后进行删除q->next这个节点
本题head指针指向的是第一个有效节点,所以我们的代码是:
Node* removeFromEnd(Node* head_, int k)
{
Node head;
head.next = head_;
Node* p = &head;
Node* q = &head;
for (int i = 0; i < k; ++i)
{
p = p->next;
if (p == nullptr)
{
return head_;
}
}
while (p->next != nullptr)
{
q = q->next;
p = p->next;
}
Node* node = q->next;
q->next = node->next;
delete node;
return head.next;
}
旋转链表
如果k的值大于链表的个数,相当于最后移动k%链表的长度个节点
我们仔细观察:
这是把末尾的k个节点直接搬到开头:
末尾的k个节点的最后一个节点的next地址域写上原来的前面的节点的地址。
head从原来的第一个有效节点指向倒数第k个节点(即现在的第一个有效节点)
3这个节点成末尾节点,需要把3这个节点的next地址域置为空
所以,我们要用一个指针指向倒数第k+1个节点(双指针的移动),将来这个节点就是末尾节点了,其next域要置为空
时间复杂度是O(n)
空间复杂度是O(1)
Node* RotateRight(Node* head, int k)
{
if (head == nullptr || k <= 0)
{
return head;
}
Node* q = head;
Node* p = head;
int number = 0;
for (Node* k = head; k != nullptr; k = k->next)
{
number++;
}
int n = k % number;
for (int i = 0; i < n; ++i)
{
p = p->next;
}
while (p->next != nullptr)
{
p = p->next;
q = q->next;
}
p->next = head;
head->next = q->next;
q->next = nullptr;
return head;
}