LeetCode Linked List Topic 19 Delete the last nth number java recursive solution && multi-pointer solution

Question details

This question is to delete the nth number from the bottom of the linked list. Because of the nature of the linked list, it must be traversed to know how long the linked list is.
In order to know which node each node is from the bottom, we use backtracking to count here, so as to count which number we are.
In addition, our logic to delete the nth number is to use the n+1th number to point to the n-1 number (reciprocal).
But there is a special case. The number n-1 must exist, it can be empty, but the number n+1 may not exist, when the number we want to delete is at the head of the linked list, the element n+1 is empty, we can use a node Point to empty, but never use an empty node to point to another node.
So we need to judge whether the nth element is the head node, if it is, then we return to the next of the head node.
The effect of the code is 100% and 99.19%

Recursive solution

This is what I did a month ago, using retrospective thinking, to find the point between n-1 and n+1.
Among them is a special case.

class Solution {
    
    
    private boolean flag = false;// 用以强制退出递归
    ListNode nSubOne = null,nPlusOne = null,nn=null;
    public ListNode removeNthFromEnd(ListNode head, int n) {
    
    
        backtrack(head,n);
        //只需要考虑一个特殊情况:删除的是头元素,则无法用n+1->n-1来删除n,那么直接返回head的next即可
        if(nn==head)
            return head.next;
        nPlusOne.next = nSubOne;
        return head;
    }
    public int backtrack(ListNode p, int n){
    
    
        if(flag)
            return 0;
        //判断是否为空
        if(p==null)
            return 0;
        int count = backtrack(p.next,n);
        count++;
        //进行判断,找到倒数n-1,n和n+1个数
        if(count==n-1)
            nSubOne = p;
        else if(count==n+1){
    
    
            nPlusOne = p;
            flag = true;
        }
        else if(count==n)
           nn = p;
        return count;
    }
}

Multi-pointer solution

Doing this question after more than a month, retrospectively forgot everything, the first reaction is more pointers.
There are three pointers in total, one preN, one nextN, and one tail.
Tail leads preN by a total of n next (that is, the interval is n-1 points), and nextN leads preN twice next (that is, one point).
When the three pointers run backward at the same time and tail.next is empty, it means that it has reached the end of the linked list. At this time, preN just went before the nth point from the bottom, and nextN just went behind the nth point from the bottom. At this time, preN.net = nextN.
Here is the same as the above, there are special circumstances, when n = the length of the linked list, that is, after the tail ran first, the next is empty, then head.next can be returned directly.
Look at the code:

class Solution {
    
    
    public ListNode removeNthFromEnd(ListNode head, int n) {
    
    
        //没有什么记忆了,感觉还是得多刷题,不然这种做过的题都没什么记忆,用什么方法还得想半天,其实很不应该
        //需要考虑的是,这个是个链表,你只能一直访问下去
        //需要找到第倒数第n个节点,
        //只用一趟就解决
        //因为n有效,所以我直接把第一个节点往后走n个,领先n,然后两个一起往后走
        //这样的话,当领先的为null时,那么就能找到第n个了
        //这里因为是要删除,所以,还得搞一个近的
        //所以是n-1是n+1,总共三个指针
        if(n==0){
    
    
            return head;
        }
        ListNode ans=head, preN=head, nextN=head, tail=head;
        //当链表长度等于n时,需要考虑,其他都不存在问题
        
        for(int i=0; i<n; i++){
    
    
            tail = tail.next;
        }
        if(tail==null){
    
    //n=链表长度
            return head.next;
        }
        
        nextN = nextN.next.next;

        while(tail.next!=null){
    
    
            tail=tail.next;
            preN = preN.next;
            nextN = nextN.next;
        }
        preN.next = nextN;
        return head;
    }
}

The time complexity is the same, both are O(n), which makes no difference, and the space complexity is also O(1), which is slightly more than the constant term above.
It's just a different idea.

Guess you like

Origin blog.csdn.net/qq_34687559/article/details/109182014