C语言算法-解答旋转链表问题的C语言实现
题目:
给你一个链表的头节点head
,旋转链表,将链表每个节点向右移动k
个位置,其中k
是非负数。
引言:
旋转链表问题要求将链表每个节点向右移动k
个位置。本文将使用C语言来解答这个算法问题,并给出C代码实现。我们会详细介绍算法思路,并进行代码实现、算法分析、示例和测试、总结。
算法思路:
为了解决旋转链表问题,我们可以将链表首尾相连,然后找到新的头节点和尾节点,断开链表。
具体算法步骤如下:
- 统计链表的长度
len
,并找到链表的尾节点tail
。 - 将链表首尾相连,形成一个环状链表。
- 计算新的头节点位置:
newHeadIndex = len - k % len - 1
,其中k % len
表示实际需要旋转的步数,减去1是为了找到新的头节点的前一个节点。 - 找到新的头节点
newHead
和新的尾节点newTail
。 - 断开环状链表,将
newTail
的next
指针置为NULL
,然后返回newHead
作为新的头节点。
代码实现:
#include <stdio.h>
#include <stdlib.h>
// Definition for singly-linked list.
struct ListNode {
int val;
struct ListNode *next;
};
struct ListNode* rotateRight(struct ListNode* head, int k) {
if (head == NULL || head->next == NULL || k == 0) {
return head;
}
struct ListNode* tail = head;
int len = 1;
while (tail->next != NULL) {
tail = tail->next;
len++;
}
k %= len;
if (k == 0) {
return head;
}
tail->next = head; // 首尾相连
int newHeadIndex = len - k - 1;
struct ListNode* newTail = head;
while (newHeadIndex > 0) {
newTail = newTail->next;
newHeadIndex--;
}
struct ListNode* newHead = newTail->next;
newTail->next = NULL; // 断开环状链表
return newHead;
}
算法分析:
- 时间复杂度:算法的时间复杂度为O(n),其中n是链表的长度。统计链表长度需要O(n)的时间,寻找新的头尾节点需要O(n)的时间,最后的断开操作也需要O(n)的时间。
- 空间复杂度:算法的空间复杂度为O(1),因为只使用了有限的额外空间来存储变量。
示例和测试:
示例1:
输入: head = [1,2,3,4,5], k = 2
输出: [4,5,1,2,3]
示例2:
输入: head = [0,1,2], k = 4
输出: [2,0,1]
总结:
通过首尾相连形成环状链表,我们用C语言实现了解决旋转链表问题的代码。这个算法在时间和空间复杂度上表现良好,适用于一般情况。希望本文能够帮助你理解解决这个算法问题的思路和方法。