将循环链表拆分为大小几乎相同的三部分
在不计算长度的情况下将给定的循环链表拆分为三部分,使得具有最大节点数的链表与具有最小节点数的链表之间的差异最小。
例子:
Input: Circular Linked List: 1->3->5->7->9
Output: 1 3
5 7
9
Input: Circular Linked List: 2->4->8
Output: 2
4
8
方法:解决这个问题的方法是使用龟兔算法。
- 将慢速、平均和快速指针移动 1、2 和 3
- 当快速指针到达 NULL 时,avg 指针到达后半部分的末尾,慢速指针到达前半部分的末尾。
- 使第三个半圆形。
- 将下半部分做成圆形。
- 将前半部分做成圆形。
- 设置两个链表的头指针
下面是上述方法的实现:
C++
// Program to split a circular linked list
// into three halves
#include
using namespace std;
/* structure for a node */
class Node {
public:
int data;
Node* next;
};
// Function to split a list
// (starting with head) into three lists.
// head1_ref, head2_ref & head3_ref are
// references to head nodes of the
// three resultant linked lists
void splitList(Node* head, Node** head1_ref,
Node** head2_ref,
Node** head3_ref)
{
Node* slow_ptr = head;
Node* avg_ptr = head->next;
Node* fast_ptr = head->next->next;
if (head == NULL
|| head->next == NULL
|| head->next->next == NULL)
return;
while (fast_ptr->next != head
&& fast_ptr->next->next != head) {
if (fast_ptr->next->next->next
!= head)
fast_ptr
= fast_ptr->next->next->next;
else {
fast_ptr = fast_ptr->next->next;
}
avg_ptr = avg_ptr->next->next;
slow_ptr = slow_ptr->next;
}
while (fast_ptr->next != head)
fast_ptr = fast_ptr->next;
// Make third half circular
*head3_ref = avg_ptr->next;
fast_ptr->next = *head3_ref;
// Make second half circular
*head2_ref = slow_ptr->next;
avg_ptr->next = *head2_ref;
// Make first half circular
*head1_ref = head;
slow_ptr->next = *head1_ref;
}
// Function to insert a node at
// the beginning of a Circular linked list
void push(Node** head_ref, int data)
{
Node* ptr1 = new Node();
Node* temp = *head_ref;
ptr1->data = data;
ptr1->next = *head_ref;
// If linked list is not NULL then
// set the next of last node
if (*head_ref != NULL) {
while (temp->next != *head_ref)
temp = temp->next;
temp->next = ptr1;
}
else
// For the first node
ptr1->next = ptr1;
*head_ref = ptr1;
}
// Function to print nodes in
// a given Circular linked list
void printList(Node* head)
{
Node* temp = head;
if (head != NULL) {
do {
cout << temp->data << " ";
temp = temp->next;
} while (temp != head);
}
cout << endl;
}
// Driver Code
int main()
{
int list_size, i;
// Initialize lists as empty
Node* head = NULL;
Node* head1 = NULL;
Node* head2 = NULL;
Node* head3 = NULL;
// Created linked list will be
// 1->3->5->7->9
push(&head, 1);
push(&head, 3);
push(&head, 5);
push(&head, 7);
push(&head, 9);
// Split the list
splitList(head, &head1, &head2, &head3);
// First Circular Linked List
printList(head1);
// Second Circular Linked List
printList(head2);
// Third Circular Linked List
printList(head3);
return 0;
}
Java
// Program to split a circular linked list
// into three halves
import java.util.*;
class GFG{
/* structure for a node */
static class Node {
int data;
Node next;
};
// Function to split a list
// (starting with head) into three lists.
// head1_ref, head2_ref & head3_ref are
// references to head nodes of the
// three resultant linked lists
static Node head1_ref;
static Node head2_ref;
static Node head3_ref;
static void splitList(Node head)
{
Node slow_ptr = head;
Node avg_ptr = head.next;
Node fast_ptr = head.next.next;
if (head == null
|| head.next == null
|| head.next.next == null)
return;
while (fast_ptr.next != head
&& fast_ptr.next.next != head) {
if (fast_ptr.next.next.next
!= head)
fast_ptr
= fast_ptr.next.next.next;
else {
fast_ptr = fast_ptr.next.next;
}
avg_ptr = avg_ptr.next.next;
slow_ptr = slow_ptr.next;
}
while (fast_ptr.next != head)
fast_ptr = fast_ptr.next;
// Make third half circular
head3_ref = avg_ptr.next;
fast_ptr.next = head3_ref;
// Make second half circular
head2_ref = slow_ptr.next;
avg_ptr.next = head2_ref;
// Make first half circular
head1_ref = head;
slow_ptr.next = head1_ref;
}
// Function to insert a node at
// the beginning of a Circular linked list
static Node push(Node head_ref, int data)
{
Node ptr1 = new Node();
Node temp = head_ref;
ptr1.data = data;
ptr1.next = head_ref;
// If linked list is not null then
// set the next of last node
if (head_ref != null) {
while (temp.next != head_ref)
temp = temp.next;
temp.next = ptr1;
}
else
// For the first node
ptr1.next = ptr1;
head_ref = ptr1;
return head_ref;
}
// Function to print nodes in
// a given Circular linked list
static void printList(Node head)
{
Node temp = head;
if (head != null) {
do {
System.out.print(temp.data+ " ");
temp = temp.next;
} while (temp != head);
}
System.out.println();
}
// Driver Code
public static void main(String[] args)
{
int list_size, i;
// Initialize lists as empty
Node head = null;
head1_ref = null;
head2_ref = null;
head3_ref = null;
// Created linked list will be
// 1.3.5.7.9
head = push(head, 1);
head = push(head, 3);
head = push(head, 5);
head = push(head, 7);
head = push(head, 9);
// Split the list
splitList(head);
// First Circular Linked List
printList(head1_ref);
// Second Circular Linked List
printList(head2_ref);
// Third Circular Linked List
printList(head3_ref);
}
}
// This code is contributed by shikhasingrajput
输出:
9 7
5 3
1
时间复杂度:O(N)
辅助空间:O(1)