题目传送门:
时间复杂度 O(N)
1.特殊情况判断:head == NULL
2.获取链表长度 length,该数据很有用,等下会用到好几次
3.k %= length,防止 k 过大出现多轮重复操作
4.找到将来的末节点和头结点,记录将来的头结点后,将来的末节点->next = NULL
举个例子:
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, NULL}
rotate 3 >>
{8, 9, 10, 1, 2, 3, 4, 5, 6, 7, NULL}
7 是将来的末节点,8 是将来的头结点
先通过 (length - k) 找到 7,记录 7->next (LinkList* ans = &8),再令 7->next = NULL
完成对将来末节点的操作
找 7 不能通过 head = head->next,因为 head 有用,不能丢失该节点信息
5.链接两子链表,完成操作
现在的子链表:{1, 2, 3, 4, 5, 6, 7, NULL} & {8, 9, 10},令 10->next = &1,之后返回 ans 即可
代码:
int Count(struct ListNode* head) {
int c = 0;
while (head) c++, head = head->next;
return c;
}
struct ListNode* rotateRight(struct ListNode* head, int k) {
if (head == NULL) return NULL;
int length = Count(head);
k %= length;//防止 k 过大出现多轮重复操作
if (!k) return head;//k == 0后续操作可能会对空指针进行,因此特判
struct ListNode* p = head;//防止丢失头结点信息
int i;
for (i = 0; i < length - k - 1; i++) p = p->next;//p找到将来的末节点
struct ListNode* ans = p->next;//ans找到将来的头结点
p->next = NULL;//分割链表
struct ListNode* q = ans;//q找到原先末节点
for (i = 0; i < k - 1; i++) q = q->next;
q->next = head;//链接两子链表
return ans;
}
还有一种写法是先链接成环再断开,之前写的是先断开再链接
这两个差不太多,代码实现我就不写了