19. 删除链表的倒数第N个节点

2022-10-08  本文已影响0人  一直流浪

19. 删除链表的倒数第N个节点

题目链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/submissions/

难度:中等

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.

说明:

给定的 n 保证是有效的。

进阶:

你能尝试使用一趟扫描实现吗?

解法一:暴力法(需要遍历两次)

遍历链表,计算出链表长度len,然后计算出需要删除的结点的下标位置tag = len - n;

再遍历链表,让需要删除的结点的上一个结点的next指向需删除结点的next结点。

复杂度分析

时间复杂度:O(L),该算法对列表进行了两次遍历,首先计算了列表的长度 L其次找到第 (L - n) 个结点。 操作执行了 2L-n 步,时间复杂度为 O(L)。

空间复杂度:O(1),我们只用了常量级的额外空间。

`

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        int len = 1;
        if(head == null) {
            return null;
        }
        ListNode node = head;
        while(node.next!=null) {
            len ++;
            node = node.next;
        }
        node = head;
        int tag = len - n;
        if(tag == 0) {
            return head.next;
        }
        while(node.next!=null) {
            tag--;
            if(tag == 0) {
                node.next = node.next.next;
                break;
            }
            node = node.next;
        }
        return head;
    }
}

`

解法二:双指针法(只要一次遍历)

我们可以使用两个指针L和R来遍历数组 , 先让两个结点的距离相聚n-1 , 起初让两个指针都指向头结点 , 然后先让R指针向后移动 n-1个结点。然后同时移动两个指针,当R指针移动到最后一个的时候,L指针指向的刚好是需要删点的结点。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode R = dummy;
        ListNode L = dummy;
        for(int i = 0;i<n+1;i++) {
            R = R.next;
        }

        while(R!=null) {
            R = R.next;
            L = L.next;
        }
        L.next = L.next.next;
        
        return dummy.next;
    }
}
上一篇下一篇

猜你喜欢

热点阅读