简体   繁体   中英

Remov n-th node from the end of list [LeetCode]

The question is very straight forward and I got the algorithm as well. The only thing I don't understand is the return statement. why do we need to return dummy.next , when we haven't make any change to dummy at all.

I guess my question is when we initially set slow and fast equal to dummy , aren't we just making a deep copy of the list/dummy (meaning whatever change we made in either of them does not affect dummy), or am i missing something..?

Any help would be appreciated. if you can back up your explanation with an example, would be awesome.

And here is link to the question:https://leetcode.com/problems/remove-nth-node-from-end-of-list/

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
         
        ListNode slow = dummy, fast = dummy;
        
        for(int i = 0; i <= n ; i++){
            fast = fast.next;
        }
        
        while(fast != null){
          fast = fast.next;
          slow = slow.next;
        }
        
        slow.next = slow.next.next;
        
        return dummy.next;
    }
}

The only difference that I can see between using the dummy and not would be in the case of having to remove the first element in the list. In that case, without using the dummy there would not be a way to remove the head node. However, this can easily be fixed by adding a simple check during the initial loop.

Here is my solution, omitting the use of the dummy head.

public ListNode removeNthFromEnd(ListNode head, int n) {
    ListNode slow = head, fast = head;
        
    for(int i = 0; i <= n ; i++){
        if (fast == null) {
            return head.next;
        }
        fast = fast.next;
    }
        
    while(fast != null){
      fast = fast.next;
      slow = slow.next;
    }
        
    slow.next = slow.next.next;
        
    return head;
}

To answer your other questions,

aren't we just making a deep of the list/dummy

there is no deep copying going on since the dummy keeps a reference of the head, not a copy.

why do we need return dummy.next, when we haven't make any change to dummy at all.

the dummy is defined to be before the head. so when we want to return the changed head, we return the next node after dummy. If we just returned dummy, then the answer that we would get would have an extra 0 in the front of it, which we don't want.

To answer your questions,

when we initially set slow and fast equal to dummy, aren't we just making a deep of the list/dummy

No it doesn't. The assignment is by reference as ListNode is a reference type. Thus changing any of dummy, slow, fast will show its affect on all three variables.

the only thing I don't understand is the return statement. why do we need return dummy.next

As for the return statement, we still need to return the start of list that was provided to us as a parameter head in function, which is being pointed by dummy.next

As for why is the operations directly not performed on head and there is need of dummy variable and steps

ListNode dummy = new ListNode(0);
dummy.next = head;

the reason might be cover up all edge scenarios. eg: Linked List contains only one node and it is removed or the first node of linked list is removed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM