题目描述
Given a linked list, rotate the list to the right by k places, where k is non-negative.
Example 1:
Input: 1->2->3->4->5->NULL, k = 2
Output: 4->5->1->2->3->NULL
Explanation:
rotate 1 steps to the right: 5->1->2->3->4->NULL
rotate 2 steps to the right: 4->5->1->2->3->NULL
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rotate-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
链表中的点已经相连,一次旋转操作意味着:
先将链表闭合成环
找到相应的位置断开这个环,确定新的链表头和链表尾
新的链表头在哪里?
在位置 n-k 处,其中 n 是链表中点的个数,新的链表尾就在头的前面,位于位置 n-k-1。
我们这里假设 k < n
如果 k >= n 怎么处理?
k 可以被写成 k = (k // n) * n + k % n 两者加和的形式,其中前面的部分不影响最终的结果,因此只需要考虑 k%n 的部分,这个值一定比 n 小。
算法实现很直接:
找到旧的尾部并将其与链表头相连 old_tail.next = head,整个链表闭合成环,同时计算出链表的长度 n。
找到新的尾部,第 (n - k % n - 1) 个节点 ,新的链表头是第 (n - k % n) 个节点。
断开环 new_tail.next = None,并返回新的链表头 new_head。
实现
class Solution {
public ListNode rotateRight(ListNode head, int k) {
// base cases
if (head == null) return null;
if (head.next == null) return head;
// close the linked list into the ring
ListNode old_tail = head;
int n;
for(n = 1; old_tail.next != null; n++)
old_tail = old_tail.next;
old_tail.next = head;
// find new tail : (n - k % n - 1)th node
// and new head : (n - k % n)th node
ListNode new_tail = head;
for (int i = 0; i < n - k % n - 1; i++)
new_tail = new_tail.next;
ListNode new_head = new_tail.next;
// break the ring
new_tail.next = null;
return new_head;
}
}
思路二(浅)
双指针法
#include <iostream>
using namespace std;
// Definition for singly-linked list.
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
/// Brute Force
/// Two Pointers
///
/// Time Complexity: O(N)
/// Space Complexity: O(1)
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
if(head == NULL)
return NULL;
int len = get_len(head);
k = k % len;
ListNode* end = head;
for(int i = 0 ; i < k ; i ++)
end = end->next;
ListNode* start = head;
while(end->next != NULL){
start = start->next;
end = end->next;
}
end->next = head;
head = start->next;
start->next = NULL;
return head;
}
private:
int get_len(ListNode* head){
int res = 0;
while(head){
res ++;
head = head->next;
}
return res;
}
};
int main() {
return 0;
}