LeetCode61 旋转链表
给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
示例 1:
输入:head = [1,2,3,4,5], k = 2
输出:[4,5,1,2,3]
示例 2:
输入:head = [0,1,2], k = 4
输出:[2,0,1]
法一:
k取模,消除不必要的循环次数:
ListNode* rotateRight(ListNode* head, int k) {
if (k == 0||head==nullptr)
return head;
ListNode* h = head;
ListNode* p = head;
ListNode* pre_p = p;
int size = 0;
while (p != nullptr) {
p = p->next;
size++;
}
int i = 0;
int realk = k % size;
p = h;
while (i++ < realk) {
while (p ->next!= nullptr) {
pre_p = p;
p = p->next;
}
pre_p->next = p->next;
p->next = h;
h = p;
}
return h;
}
法二
先变成一个循环链表,再从适当位置断开
//其实本质上是将尾部向前数第K个元素作为头,原来的头接到原来的尾
ListNode* rotateRight2(ListNode* head, int k) {
if (k == 0 || head == nullptr)
return head;
ListNode* h = head;
ListNode* p = head;
ListNode* pre_p = p;
int size = 1,i=0; //至少有一个元素
while (p->next != nullptr) {
p = p->next;
size++;
}
p->next = h; //循环链表
int realk = k % size;
p = h; //p指向头节点
ListNode* q = h;
int move = size - realk - 1; //q从头节点开始移动move步等价于p从尾部向后移动k步
while (i++<move) {
q = q->next;
}
//从q处断开,q->next就是旋转后的头节点
h = q->next;
q->next = nullptr; //断开循环链表
return h;
}