• LeetCode算法扫题系列19


    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9104677.html

    LeetCode算法第19题(难度:中等)

    题目:给定一个链表,删除链表的倒数第 个节点,并且返回链表的头结点。(English:Given a linked list, remove the n-th node from the end of list and return its head.

    示例:

    给定一个链表: 1->2->3->4->5, 和 n = 2.
    
    当删除了倒数第二个节点后,链表变为 1->2->3->5.

    说明:

    给定的 n 保证是有效的。

    进阶:

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

    提示:Maintain two pointers and update one with a delay of n steps.

    简述实现思路:

      普通思路:那就是两次遍历,首次遍历需要查出列表的长度,第二次遍历根据n找到指定删除的节点,删除即可。

      进阶思路:根据提示中的内容,我们设立两个指针,分别指向相距n个节点的两个节点,然后保持n间距不变,遍历列表,当后面指针到达链表尾节点的时候,那么前面的指针正好指向的是待删除的节点。

    Java代码实现:(简单实现)

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 class Solution {
    10     public ListNode removeNthFromEnd(ListNode head, int n) {
    11         ListNode node = head;
    12         int length = 0;
    13         do {
    14             length++;
    15             node = node.next;
    16         } while(node !=null);//结束时node指向尾节点
    17         
    18         if(n == length){//删除头结点
    19             return head.next;
    20         }else{
    21             node = head;
    22             int m = 0;
    23             while(true){
    24                 m++;
    25                 if(m == length - n){//找到待删元素的前一个元素
    26                     node.next = node.next.next;
    27                     break;
    28                 }
    29                 node = node.next;
    30             }
    31         }
    32         return head;
    33     }
    34 }

    (进阶实现)

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 class Solution {
    10     public ListNode removeNthFromEnd(ListNode head, int n) {
    11         ListNode node = head;
    12         ListNode preNode = null;
    13         int m = 0;
    14         boolean isFirst = true;
    15         while(node != null){
    16             m++;
    17             if(m > n){
    18                 isFirst = false;
    19                 if(m == n + 1){
    20                     preNode = head;
    21                 }else{
    22                     preNode = preNode.next;
    23                 }
    24             }
    25             node = node.next;
    26         }
    27         if(isFirst){
    28             return head.next;
    29         }
    30         preNode.next = preNode.next.next;
    31         return head;
    32     }
    33 }

      进阶思路解析:node节点可以看成是遍历条件,也可以看成是双指针的后指针,当这个指针移动到尾节点时,前指针就就位了,其实前指针指向的是待删节点的前节点,也就是说两个指针之间的距离其实是n+1。遍历开始后m递增,当m<=n的时候只移动后指针,当m>n时前指针开始移动。这样当遍历结束,前指针就位删除其后一个节点即可。注意头节点需要单独处理,处理逻辑为27-29行,当然也包括18行的逻辑。

  • 相关阅读:
    C语言、指针的指针和野指针的问题
    常见证书格式和转换
    cation,validation,qualification有何区别
    Cygwin + OpenSSH FOR Windows的安装配置
    python static variable
    45个与众不同的非常棒网页设计案例
    65个精心设计的富有灵感的电子商务网站案例
    60个抢眼的企业网站设计案例
    26个有用的创建视觉图片网站的jQuery插件
    Android 图像用户界面免费的PSD设计文件
  • 原文地址:https://www.cnblogs.com/V1haoge/p/9104677.html
Copyright © 2020-2023  润新知