📜  以给定大小的组反转单向链表 |第 4 组(空间高效的方法)

📅  最后修改于: 2022-05-13 01:57:45.350000             🧑  作者: Mango

以给定大小的组反转单向链表 |第 4 组(空间高效的方法)

给定一个链表,编写一个函数来反转每个 k 节点(其中 k 是函数的输入)。例子:

已在以下帖子中讨论了上述问题的多种方法:

  • 以给定大小的组反转链表 |设置 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 现场工作专业课程学生竞争性编程现场课程