Home > Net >  Problems with LinkedList, overwritten?
Problems with LinkedList, overwritten?

Time:08-05

I have recently been working on this problem: Reorder List - Leetcode 143 and found out I don't have the concept of Linked List as clear as I imagined. The answer looks as following (got it from Grokking the coding interview):

static void reorder(ListNode *head) {
    if (head == nullptr || head->next == nullptr) {
      return;
    }

    // find the middle of the LinkedList
    ListNode *slow = head, *fast = head;
    while (fast != nullptr && fast->next != nullptr) {
      slow = slow->next;
      fast = fast->next->next;
    }

    // slow is now pointing to the middle node
    ListNode *headSecondHalf = reverse(slow);  // reverse the second half
    ListNode *headFirstHalf = head;

    // rearrange to produce the LinkedList in the required order
    while (headFirstHalf != nullptr && headSecondHalf != nullptr) {
      ListNode *temp = headFirstHalf->next;
      headFirstHalf->next = headSecondHalf;
      headFirstHalf = temp;

      temp = headSecondHalf->next;
      headSecondHalf->next = headFirstHalf;
      headSecondHalf = temp;
    }

    // set the next of the last node to 'null'
    if (headFirstHalf != nullptr) {
      headFirstHalf->next = nullptr;
    }
  }

The problem comes in the following part:

headFirstHalf->next = headSecondHalf;
headFirstHalf = temp;

If I overwrite the next node of headFirstHalf to be the node headSecondHalf and then I overwrite the headFirstHalf, wouldn't I be overwriting the headFirstHalf->next by assigning headFirstHalf to temp?

I hope the question is clear, otherwise I'll try to make myself clearer, Thanks

CodePudding user response:

The variables that are of the ListNode* type, are pointers. They are not the structures themselves. It may help to visualise this. When the while loop starts, we might have this state:

head  headFirstHalf
  │    │
  ▼    ▼
┌────────────┐   ┌────────────┐
│ data: 1    │   │ data: 2    │
│ next: ───────► │ next: null │
└────────────┘   └────────────┘


┌────────────┐   ┌────────────┐
│ data: 4    │   │ data: 3    │
│ next: ───────► │ next: null │
└────────────┘   └────────────┘
  ▲
  │
headSecondHalf

Then we execute

ListNode *temp = headFirstHalf->next;
head  headFirstHalf  temp
  │    │              │
  ▼    ▼              ▼
┌────────────┐   ┌────────────┐
│ data: 1    │   │ data: 2    │
│ next: ───────► │ next: null │
└────────────┘   └────────────┘


┌────────────┐   ┌────────────┐
│ data: 4    │   │ data: 3    │
│ next: ───────► │ next: null │
└────────────┘   └────────────┘
  ▲
  │
headSecondHalf

Now we get to the statements that you asked about. First:

headFirstHalf->next = headSecondHalf;
head  headFirstHalf  temp
  │    │              │
  ▼    ▼              ▼
┌────────────┐   ┌────────────┐
│ data: 1    │   │ data: 2    │
│ next: ─┐   │   │ next: null │
└────────│───┘   └────────────┘
         │
         ▼
┌────────────┐   ┌────────────┐
│ data: 4    │   │ data: 3    │
│ next: ───────► │ next: null │
└────────────┘   └────────────┘
  ▲
  │
headSecondHalf

And then

headFirstHalf = temp;
head  headFirstHalf  temp
  │    └───────────┐  │
  ▼                ▼  ▼
┌────────────┐   ┌────────────┐
│ data: 1    │   │ data: 2    │
│ next: ─┐   │   │ next: null │
└────────│───┘   └────────────┘
         │
         ▼
┌────────────┐   ┌────────────┐
│ data: 4    │   │ data: 3    │
│ next: ───────► │ next: null │
└────────────┘   └────────────┘
  ▲
  │
headSecondHalf

This should already be enough to answer your question, but let's just finish the rest of the body of the while loop.

temp = headSecondHalf->next;
head  headFirstHalf
  │    └───────────┐
  ▼                ▼
┌────────────┐   ┌────────────┐
│ data: 1    │   │ data: 2    │
│ next: ─┐   │   │ next: null │
└────────│───┘   └────────────┘
         │
         ▼
┌────────────┐   ┌────────────┐
│ data: 4    │   │ data: 3    │
│ next: ───────► │ next: null │
└────────────┘   └────────────┘
  ▲                ▲
  │                │
headSecondHalf    temp

Continue with:

headSecondHalf->next = headFirstHalf;
head  headFirstHalf
  │    └───────────┐
  ▼                ▼
┌────────────┐   ┌────────────┐
│ data: 1    │   │ data: 2    │
│ next: ─┐   │ ┌►│ next: null │
└────────│───┘ │ └────────────┘
         │     │
         ▼     │
┌────────────┐ │ ┌────────────┐
│ data: 4    │ │ │ data: 3    │
│ next: ───────┘ │ next: null │
└────────────┘   └────────────┘
  ▲                ▲
  │                │
headSecondHalf    temp

And finally:

headSecondHalf = temp;
head  headFirstHalf
  │    └───────────┐
  ▼                ▼
┌────────────┐   ┌────────────┐
│ data: 1    │   │ data: 2    │
│ next: ─┐   │ ┌►│ next: null │
└────────│───┘ │ └────────────┘
         │     │
         ▼     │
┌────────────┐ │ ┌────────────┐
│ data: 4    │ │ │ data: 3    │
│ next: ───────┘ │ next: null │
└────────────┘   └────────────┘
                   ▲ ▲
  ┌────────────────┘ │
headSecondHalf      temp

Then the next iteration starts...

I hope this has clarified it.

  • Related