C++程序 计算已排序旋转链表中的旋转数
在面试中,经常会遇到计算旋转链表的问题。旋转链表是一种具有循环移位的链表,即将链表的最后一个元素移到第一个元素之前。但是,并不是所有旋转链表都是由顺序排列的,因此需要计算已排序旋转链表中旋转的元素。在本文中,我们将介绍如何通过使用C++编写程序来计算已排序旋转链表中的旋转数。
什么是旋转链表?
首先,让我们来了解一下什么是旋转链表。旋转链表是一个环形链表,最后一个元素后面连接到第一个元素之前。例如,以下是一个旋转链表的示例:
1->2->3->4->5->1->2->3->4->5->1->2->3->4...
需要注意的是,所有的旋转链表都是有序的。
旋转数是什么?
旋转链表由顺序链表旋转而成。链表中被旋转的元素的数量被称为旋转数。例如,以下是一个旋转数为2的旋转链表的示例:
3->4->5->1->2->3->4->5->1->2->3->4...
旋转数是非常重要的,因为它可以告诉我们进行旋转的次数。通过计算旋转数,我们可以确定在旋转操作中,需要将链表移位几次才能完成所有操作。
如何计算已排序旋转链表中的旋转数?
在C++中,计算已排序旋转链表中的旋转数可以通过以下三个步骤完成:
第一步:查找中间节点
首先,需要找到链表的中间节点。为了完成这个步骤,可以使用快慢指针的方法。快指针每次向前移动两个位置,而慢指针每次移动一个位置。快指针到达链表末尾时,慢指针应该正好在链表的中间。以下是示例代码:
ListNode* findMiddle(ListNode* head) {
ListNode* slow = head;
ListNode* fast = head;
while (fast != nullptr && fast->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
第二步:查找中间节点后的下一个节点
一旦找到链表的中间节点,接下来需要找到中间节点后的下一个节点。此节点是旋转位置。以下是示例代码:
ListNode* findRotation(ListNode* head) {
ListNode* middle = findMiddle(head);
ListNode* rotation = middle->next;
middle->next = nullptr;
return rotation;
}
第三步:计算旋转数
最后,需要计算中间节点的下一个节点(旋转位置)的位置,以确定旋转数。以下是示例代码:
int findRotateCount(ListNode* head) {
ListNode* rotation = findRotation(head);
ListNode* current = rotation;
int count = 1;
while (current->next != nullptr) {
current = current->next;
count++;
}
return count;
}
完整代码
以下是计算已排序旋转链表中的旋转数的完整代码:
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(nullptr) {}
};
ListNode* findMiddle(ListNode* head) {
ListNode* slow = head;
ListNode* fast = head;
while (fast != nullptr && fast->next != nullptr) {
slow = slow->next;
fast =fast->next->next;
}
return slow;
}
ListNode* findRotation(ListNode* head) {
ListNode* middle = findMiddle(head);
ListNode* rotation = middle->next;
middle->next = nullptr;
return rotation;
}
int findRotateCount(ListNode* head) {
ListNode* rotation = findRotation(head);
ListNode* current = rotation;
int count = 1;
while (current->next != nullptr) {
current = current->next;
count++;
}
return count;
}
int main() {
ListNode* head = new ListNode(1);
ListNode* node1 = new ListNode(2);
ListNode* node2 = new ListNode(3);
ListNode* node3 = new ListNode(4);
ListNode* node4 = new ListNode(5);
head->next = node1;
node1->next = node2;
node2->next = node3;
node3->next = node4;
node4->next = head;
int rotateCount = findRotateCount(head); // 0
ListNode* newHead = new ListNode(3);
ListNode* newNode1 = new ListNode(4);
ListNode* newNode2 = new ListNode(5);
ListNode* newNode3 = new ListNode(1);
ListNode* newNode4 = new ListNode(2);
newHead->next = newNode1;
newNode1->next = newNode2;
newNode2->next = newNode3;
newNode3->next = newNode4;
newNode4->next = newHead;
rotateCount = findRotateCount(newHead); // 2
cout << "Rotate count is: " << rotateCount << endl;
return 0;
}
在上面的代码中,我们创建了一个包含5个元素的链表,并将其连接到环的起点。然后,我们计算旋转数,并打印结果为0。接下来,我们创建了一个具有两个元素旋转的链表,并再次计算旋转数。此时,结果应该是2。最后,我们打印旋转数。
结论
通过使用C++,可以轻松计算已排序旋转链表中的旋转数。通过遵循上述三个步骤,可以在面试中便捷地解决旋转链表的相关问题。