4

There is a singly connected linked list and a block size is given.For eg if my linked list is 1->2->3->4->5->6->7->8-NULL and my block size is 4 then reverse the first 4 elements and then the second 4 elements.The output of the problem should be 4->3->2->1->8->7->6->5-NULL

I was thinking of dividing the linked list into segments of size 4 and then reversing it. But that way I am forced to use a lot of extra nodes which is not desired at all. The space complexity should be kept to a minimum.

It will be highly appreciable if someone can come with a better solution where the usage of extra nodes would be kept to a minimum.

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
Poulami
  • 1,047
  • 3
  • 13
  • 27

3 Answers3

2

I tried this...seems to work fine...

node* reverse(node* head) // function to reverse a list
{
    node* new_head = NULL;
    while(head != NULL)
    {
        node* next = head->next;
        head->next = new_head;
        new_head = head;
        head = next;
    }
    return new_head;
}

node* reverse_by_block(node* head, int block)
{
    if(head == NULL)
            return head;

    node* tmp = head;
    node* new_head = head;
    node* new_tail = NULL;

    int count = block;
    while(tmp != NULL && count--)
    {
        new_tail = tmp;
        tmp = tmp->next;
    }

    new_tail->next = NULL;
    new_tail = new_head;
    new_head = reverse(new_head);
    new_tail->next = reverse_by_block(tmp,block);

    return new_head;
}
josh
  • 13,793
  • 12
  • 49
  • 58
0

You can advance swapping the current element with the next 3 times: 1234, 2134, 2314, 2341. Then do it twice to get 3421. Then once to get 4321. Then advance 4 steps and repeat the process with the next block.

LaC
  • 12,624
  • 5
  • 39
  • 38
  • I have to reverse the nodes not just the data elements. – Poulami Aug 08 '11 at 13:28
  • Yes. To swap A and B, with P being the node before A (you kept track of this while scanning), do P.next=B, A.next=B.next, B.next=A. – LaC Aug 08 '11 at 14:36
0

This can be done in linear-time, with constant space. Here is a brief description:

  1. Split the linked list into two parts by block-size

    
    int split(node* head, node** listA, node** listB size_t block_size)
    {
    node* cur = head;
    
    while(block_size && cur)
    {
       cur = cur->next;
       --block_size;
    }
    if(!cur) { /* error : invalid block size */ return -1; }
    *listA = head;
    *listB = cur->next;
    cur->next = NULL; /* terminate list A */
    return 0;
    }
    
  2. Reverse the two sub-parts, (use a non-recursive linear time, constant space function)

    
    reverse(listA);
    reverse(listB);
    
  3. Link them to get the desired linked list.

    
    cur = *listA;
    /* goto last but one element of listA */
    while(cur->next) cur = cur->next; 
    cur->next = *listB;
    
vine'th
  • 4,890
  • 2
  • 27
  • 27