• 【leetcode】19. 删除链表的倒数第 N 个结点


    题目:19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode) (leetcode-cn.com)

    思路1:

      设链表的长度为n,删除倒数第k个结点;倒数第k个节点即是第n-k+1个节点;

      一般的思路是先遍历链表得到长度n,再找到第n-k+1个节点的前驱节点n-k,对其删除。需要对两个进行两次遍历

    思路二:

      只用一次遍历就可以找到前驱节点;

      1.有两个指针p1和p2平且都指向头节点,先让p1走k步,剩下再走n-k步p1为空

      2.此时让p2,p1以同样的速度走n-k步骤,此时p1为null,p2正好指向的是第n-k+1个节点,即要删除的节点

     如果要找到前驱节点,只要使这里的k变成k+1即可:

    方法函数如下:

    public ListNode findPrevious(ListNode head,int k){
           ListNode p1,p2;
           p1 = p2 = head;
           //p1先走k步
           for(int i=0;i<k;i++){
               p1 = p1.next;
           }
           
           // p1和p2走n-k步
           while(p1!=null){
               p1 = p1.next;
               p2 = p2.next;
           }
    
           //此时p2指向的节点为第n-k+1个节点
           return p2;
       }

    通过上面的函数可以找到前驱节点第n-k个节点,即倒数第k+1个节点

    ListNode prev= findPrevious(head,n+1);

    为了防止出现空指针的情况,比如说链表总共有 5 个节点,题目就让你删除倒数第 5 个节点,也就是第一个节点,那按照算法逻辑,应该首先找到倒数第 6 个节点。但第一个节点前面已经没有节点了,这就会出错。设置虚拟节点

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode() {}
     *     ListNode(int val) { this.val = val; }
     *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     * }
     */
    class Solution {
       public ListNode removeNthFromEnd(ListNode head, int n) {
           
           
            ListNode dumpy = new ListNode(-1);
            dumpy.next = head;
           // 找到第n-k个节点
           ListNode prev= findPrevious(dumpy,n+1);
           //删除第n-k+1节点
           prev.next = prev.next.next;
    
           return dumpy.next;
       }
    
       public ListNode findPrevious(ListNode head,int k){
           ListNode p1,p2;
           p1 = p2 = head;
           //p1先走k步
           for(int i=0;i<k;i++){
               p1 = p1.next;
           }
           
           // p1和p2走n-k步
           while(p1!=null){
               p1 = p1.next;
               p2 = p2.next;
           }
    
           //此时p2指向的节点为第n-k+1个节点
           return p2;
       }
    
         
    }
  • 相关阅读:
    P4715 【深基16.例1】淘汰赛
    P4913 【深基16.例3】二叉树深度
    P1478 陶陶摘苹果(升级版)
    P1223 排队接水
    【深基12.例1】部分背包问题
    全排列和组合
    P1036 选数
    100——第25例
    100——第24例
    100——第23例
  • 原文地址:https://www.cnblogs.com/xiangshigang/p/16213791.html
Copyright © 2020-2023  润新知