以给定大小的组反转单向链表 |第 4 组(空间高效的方法)
给定一个链表,编写一个函数来反转每个 k 节点(其中 k 是函数的输入)。例子:
Inputs: 1->2->3->4->5->6->7->8->NULL, k = 3
Output: 3->2->1->6->5->4->8->7->NULL
Inputs: 1->2->3->4->5->6->7->8->NULL, k = 5
Output: 5->4->3->2->1->8->7->6->NULL
已在以下帖子中讨论了上述问题的多种方法:
- 以给定大小的组反转链表 |设置 1 -> 使用 O(n/k) 额外空间的递归
- 以给定大小的组反转链表 |设置 2 -> 使用 O(k) 额外空间的堆栈
- 以给定大小的组反转单向链表 |设置 3 -> 使用带有 O(k) 额外空间的双端队列
方法:本文重点介绍一种使用O(1)辅助空间的方法。以下是要遵循的步骤:
- 跟踪链表中每组k 个元素的指针中的第一个节点。
- 使用此算法从当前组的第一个节点反转下 k 个元素的顺序。
- 反转后,当前组的第一个节点将成为最后一个节点。将其与第k+1个连接 链表的节点。
- 第k+1个节点将成为下一组k 个元素的第一个节点。类似地,对每组k 个元素重复该过程,直到遍历整个链表。
下面是上述方法的实现:
C++
// C++ program to reverse a linked
// list in groups of given size
#include
using namespace std;
// Linked list Node
class Node {
public:
int data;
Node* next;
Node(int d)
{
data = d;
next = NULL;
}
};
void reverse(Node** node, int k)
{
if (k == 1)
return;
// Keeps track of the final list
Node* result = NULL;
// Append a new node at initial step
Node* head = new Node(0);
head->next = *(node);
Node* next = (*node)->next;
int count = 0;
while (next) {
count++;
// Update the pointer and
// iterate linked list by
// using node & next pointer
Node* tmp = next->next;
next->next = *(node);
*(node) = next;
next = tmp;
if (count == k - 1) {
count = 0;
if (result == NULL)
result = *(node);
// Last step to join the
// reversed k-group with
// the linked list
tmp = head->next;
tmp->next = next;
head->next = *(node);
head = tmp;
// Move on to the next k-group
*(node) = next;
if (*(node)!= NULL)
next = (*node)->next;
}
}
// Process last elements
Node* tmp = head->next;
if (tmp)
tmp->next = NULL;
head->next = *(node);
*(node) = result;
return;
}
// Utility functions
// Function to inserts a new
// Node at front of the list
void push(Node** head,int new_data)
{
Node* new_node = new Node(new_data);
new_node->next = *(head);
*(head) = new_node;
}
// Function to print linked list
void printList(Node** head)
{
Node* temp = *(head);
while (temp) {
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
/* Driver program to test above functions */
int main()
{
Node* head = NULL;
/* Constructed Linked List is
* 1->2->3->4->5->6->7->8->null */
push(&head,8);
push(&head,7);
push(&head,6);
push(&head,5);
push(&head,4);
push(&head,3);
push(&head,2);
push(&head,1);
reverse(&head, 3);
printList(&head);
return 0;
}
// This code is contributed by maddler.
Java
// Java program to reverse a linked
// list in groups of given size
class LinkedList {
// head of list
Node head;
// Linked list Node
class Node {
int data;
Node next;
Node(int d)
{
data = d;
next = null;
}
}
Node reverse(Node node, int k)
{
if (k == 1)
return node;
// Keeps track of the final list
Node result = null;
// Append a new node at initial step
Node head = new Node(0);
head.next = node;
Node next = node.next;
int count = 0;
while (next != null) {
count++;
// Update the pointer and
// iterate linked list by
// using node & next pointer
Node tmp = next.next;
next.next = node;
node = next;
next = tmp;
if (count == k - 1) {
count = 0;
if (result == null)
result = node;
// Last step to join the
// reversed k-group with
// the linked list
tmp = head.next;
tmp.next = next;
head.next = node;
head = tmp;
// Move on to the next k-group
node = next;
if (node != null)
next = node.next;
}
}
// Process last elements
Node tmp = head.next;
if (tmp != null)
tmp.next = null;
head.next = node;
return result;
}
// Utility functions
// Function to inserts a new
// Node at front of the list
public void push(int new_data)
{
Node new_node = new Node(new_data);
new_node.next = head;
head = new_node;
}
// Function to print linked list
void printList()
{
Node temp = head;
while (temp != null) {
System.out.print(temp.data + " ");
temp = temp.next;
}
System.out.println();
}
/* Driver program to test above functions */
public static void main(String args[])
{
LinkedList llist = new LinkedList();
/* Constructed Linked List is
* 1->2->3->4->5->6->7->8->null */
llist.push(8);
llist.push(7);
llist.push(6);
llist.push(5);
llist.push(4);
llist.push(3);
llist.push(2);
llist.push(1);
llist.head = llist.reverse(llist.head, 3);
llist.printList();
}
}
输出
3 2 1 6 5 4 8 7
时间复杂度: O(N)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。