题目:Given a linked list, remove the nth node from the end of list and return its head.For example,

   Given linked list: 1->2->3->4->5, and n = 2.

   After removing the second node from the end, the linked list becomes 1->2->3->5.

就是让你删除单链表倒数第n个节点,同时希望能只遍历一次。

解法一: 如果不遍历完所有节点,怎么知道倒数第n个在哪里呢?但是遍历完成以后,删除不是又需要遍历么?不过删除一个node实际上只需要一个pre node就行了。于是,考虑使用一个HashMap保存遍历过的节点,实现删除。

 public ListNode removeNthFromEnd(ListNode head, int n) {
// Start typing your Java solution below
// DO NOT write main() function
if(head == null) return null;
HashMap<Integer, ListNode> map = new HashMap<Integer, ListNode>();
int i = 0;
ListNode p = head;
while(p != null){
map.put(++i, p);
p = p.next;
}
ListNode pre = map.get(i - n);//i - n is the node that right BEFORE the to-be-deleted node.
if(pre != null){
ListNode deleted = pre.next;
if(deleted != null)
pre.next = deleted.next;
}else {//if pre is null, means we are deleting head
head = head.next;
}
return head;
}

HashSet deletion

感觉每次做题,如果用到了额外的数据结构或者空间,都有一种开挂的感觉。能不能不显式使用额外的空间或者数据结构呢?想到最近看了Algorithm 4th edtion关于递归删除BST的方法,有一些启发。

解法二: 我们尝试使用递归来解。

 public ListNode removeNthFromEnd2(ListNode head, int n) {
if(head == null) return null;
int[] counter = new int[]{0};
return removeNthFromEnd2(head,n,counter);
} private static ListNode removeNthFromEnd2(ListNode head, int n, int[] counter){
if(head.next == null){// we reached tail
counter[0] = 1;
}else {
head.next = removeNthFromEnd2(head.next, n, counter);
counter[0]++;//we increment this counter to record when we back from the recursive, namely back from the last node
}
if(counter[0] == n){//oh, this is nth node backward, we just RETURN THE NEXT NODE.
return head.next;
}else return head;//otherwise return whatever we received
}

recursive deletion

是不是看上去很简洁?同样的,我们还是需要遍历完所有节点。但是递归的好处是每次返回的都是“backward",通过这个特点,我们使用一个counter变量,在递归返回的时候,记录返回经过的节点(Java不如C#,没有ref参数,所以只能用一个数组记录这个counter变量以达到引用的效果)。这样当counter到打n的时候,我们知道,哦,好啦这个当前节点就是我们要删除的节点咯。所以,instead of直接返回head节点,我们返回删除节点的next,这样,在递归调用再次返回的时候,pre的next就指向了删除节点的next咯。

好吧,承认实际上这也是遍历了两次链表。。。:<

解法三: 为了减少遍历,我们还可以用两个指针slow和fast,fast先走n步。then,slow和fast共同进步直到fast走到尾巴。Code在这里

LeetCode 笔记系列四 Remove Nth Node From End of List的更多相关文章

  1. LeetCode解题报告—— 4Sum & Remove Nth Node From End of List & Generate Parentheses

    1. 4Sum Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + ...

  2. leetcode第19题--Remove Nth Node From End of List

    Problem: Given a linked list, remove the nth node from the end of list and return its head. For exam ...

  3. LeetCode之“链表”:Remove Nth Node From End of List

    题目链接 题目要求: Given a linked list, remove the nth node from the end of list and return its head. For ex ...

  4. LeetCode题解:(19) Remove Nth Node From End of List

    题目说明 Given a linked list, remove the nth node from the end of list and return its head. For example, ...

  5. LeetCode(19) Remove Nth Node From End of List

    题目 Given a linked list, remove the nth node from the end of list and return its head. For example, G ...

  6. 【leetcode❤python】 19. Remove Nth Node From End of List

    #-*- coding: UTF-8 -*-#双指针思想,两个指针相隔n-1,每次两个指针向后一步,当后面一个指针没有后继了,前面一个指针的后继就是要删除的节点# Definition for sin ...

  7. leetcode个人题解——#19 Remove Nth Node From End of List

    思路:设置两个指针,其中第二个指针比第一个延迟n个元素,这样,当第二个指针遍历到指针尾部时,对第一个指针进行删除操作. 当然,这题要注意一些边界值,比如输入[1,2] n=2时如果按照思路走会指向未分 ...

  8. LeetCode: Remove Nth Node From End of List 解题报告

    Remove Nth Node From End of List Total Accepted: 46720 Total Submissions: 168596My Submissions Quest ...

  9. 《LeetBook》leetcode题解(19):Remove Nth Node From End of List[E]——双指针解决链表倒数问题

    我现在在做一个叫<leetbook>的开源书项目,把解题思路都同步更新到github上了,需要的同学可以去看看 这个是书的地址: https://hk029.gitbooks.io/lee ...

随机推荐

  1. 从pdf 文件中抽取特定的页面

    前段时间买了一个kindle 电子书阅读器.我想用它来读的pdf文档.当然最主要是用来读python标准库&mysql的官方文档. 问题就来了.这两个都是大头书.之前用mac看还好.用kind ...

  2. 自己工作之余做的OSX小软件

    ShareSDK是为iOS.Android.WindowsPhone提供社会功能的一个组件,开发者只需10分钟即可集成到自己的APP中,它不仅支持分享给QQ好友.微信好友.微信朋友圈.新浪微博.腾迅微 ...

  3. Openresty支持HTTP2

    1. 下载openresty-1.13.6.1.tar.gz和openssl-1.0.2l.tar.gz,并解压 下载对应的软件版本,创建openresty_http2安装路径 2. 安装openre ...

  4. 【Android】16.2 Started Services

    分类:C#.Android.VS2015: 创建日期:2016-03-01 一.简介 Started Service是指被同一个应用程序的某个对象显式启动,或者在设备引导时就已经启动了(配置了服务的情 ...

  5. location [=|$|最长原则|^~](nginx-1.4.4)

    优先级由上到下依次递减: location =/a/1.png { return 400; } } location ~* \.png$ { return 403; } location /a/1.p ...

  6. 批处理-IF详解

    在CMD使用IF /?打开IF的系统帮助(自己看我就不全部列出来了),我们会发现IF有3种基本的用法! IF [NOT] ERRORLEVEL number command IF [NOT] stri ...

  7. 获取Oracle数据库中字段信息

    select t.DATA_PRECISION,t.DATA_SCALE,t.DATA_LENGTH,t.DATA_TYPE,t.COLUMN_NAME, t.NULLABLE,t.DATA_DEFA ...

  8. 容易造成JavaScript内存泄露几个方面

    高效的JavaScript Web应用必须流畅,快速.与用户交互的任何应用程序,都需要考虑如何确保内存有效使用,因为如果消耗过多,页面就会崩溃,迫使用户重新加载.而你只能躲在角落哭泣. 自动垃圾收集是 ...

  9. java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明)

    转载地址:http://www.devba.com/index.php/archives/4581.html java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明); ...

  10. Bitmap转灰度字节数组byte[]

    工作中遇到图片转灰度数组的须要,经过研究和大神的指导.终于得到例如以下两个方法.能够实现位图转灰度数组 简单的位图转灰度数组就是:得到位图中的每一个像素点,然后依据像素点得到RGB值,最后对RGB值, ...