题目: 输入一个链表。输出该链表中倒数第k哥结点。

 为了符合大多数人的习惯,本题从1開始计数。即链表的尾结点是倒数第1个结点。

比如一个链表有6个结点。从头结点開始它们的值依次是1。2。3,4,5,6.这个链表的倒数第3个结点是值为4的结点

为了得到第K个结点,非常自然的想法是先走到链表的尾端。再从尾端回溯K步。

但是我们从链表结点的定义可疑看出本题中的链表 是单向链表,单向链表的结点仅仅有从前往后的指针而没有从后往前的指针,因此这样的思路行不通。

既然不能从尾节点開始遍历这个链表。我们还是把思路回到头结点上来。

如果整个链表有N个结点,那么倒数第K哥结点就是从头结点開始的第n-k-1个结点。如果我们仅仅要从头结点開始往后走n-k+1步就可疑了。怎样得到节点数n?

这个不难,仅仅须要从头開始遍历链表,没经过一个结点,计数器加1即可了。

也就是说我们须要遍历链表两次,第一次统计出链表中结点的个数。第二次就能找到倒数第k个结点。可是当我们把这个思路解释给面试官之后,他会告诉我们他期待的解法仅仅须要遍历链表一次。

为了实现仅仅遍历链表一次就能找到倒数第k个结点。我们能够定义两个指针。第一个指针从链表的头指针開始遍历向前走k-1。第二个指针保持不动;从第k步開始,第二个指针也开化寺从链表的头指针開始遍历。

因为两个指针的距离保持在k-1。当第一个(走在前面的)指针到达链表的尾指结点时,第二个指针正好是倒数第k个结点。

不少人在面试前从网上看到过这道用两个指针遍历的思路来解答这道题。因此听到面试官的这道题,他们心中一喜,非常快就写出了代码。但是几天后等来的不是Offer,而是拒信。于是百思不得其解。事实上原因非常easy。就是自己的代码不够鲁棒。

面试官能够找出3种方法让这段代码崩溃。

1、输入Head指针为Null。

因为代码会试图訪问空指针指向的内存,程序会崩溃。

2、输入以Head为头结点的链表的结点总数少于k。因为在for循环中会在链表向前走k-1步。仍然会因为空指针造成崩溃。

3、输入的參数k为0.或负数,相同会造成程序的崩溃。

这么简单的代码存在3哥潜在崩溃的风险,我们能够想象当面试官看到这种代码会是什么心情。终于他给出的是拒信而不是Offer。

下面我们给出Java版的代码:

/**
* 输入一个链表。输出该链表中倒数第k哥结点。
* 为了符合大多数人的习惯,本题从1開始计数,即链表的尾结点是倒数第1个结点。
* 比如一个链表有6个结点。从头结点開始它们的值依次是1。2。3,4,5。6.这个链表的倒数第3个结点是值为4的结点
*/
package swordForOffer; import utils.ListNode; /**
* @author JInShuangQi
*
* 2015年8月1日
*/
public class E15KthNodeFromEnd {
public ListNode FindKthToTail(ListNode head,int k){
if(head == null || k <= 0){
return null;
}
ListNode ANode = head;
ListNode BNode = null;
for(int i = 0;i<k-1;i++){
if(ANode.next != null)
ANode = ANode.next;
else
return null;
}
BNode = head;
while(ANode.next != null){
ANode = ANode.next;
BNode = BNode.next;
}
return BNode;
}
public static void main(String[] args){
ListNode head = new ListNode();
ListNode second = new ListNode();
ListNode third = new ListNode();
ListNode forth = new ListNode();
head.next = second;
second.next = third;
third.next = forth;
head.data = 1;
second.data = 2;
third.data = 3;
forth.data = 4;
E15KthNodeFromEnd test = new E15KthNodeFromEnd();
ListNode result = test.FindKthToTail(head, -1);
System.out.println(result);
}
}

測试用例;功能測试(第k个结点在链表的中间,第k个结点在链表的头结点。第k个结点在链表的尾结点)

特殊输入測试:链表的头结点为Null指针,链表的头结点综述少于k。k等于0

剑指Offer面试题15(Java版):链表中倒数第K个结点的更多相关文章

  1. 《剑指offer》— JavaScript(14)链表中倒数第k个结点

    链表中倒数第k个结点 题目描述 输入一个链表,输出该链表中倒数第k个结点. 思路 两个指针,先让第一个指针和第二个指针都指向头结点,然后再让第一个指正走(k-1)步,到达第k个节点: 然后两个指针同时 ...

  2. C++版 - 剑指offer 面试题63:二叉搜索树的第k个结点(二叉树中序遍历的应用) 题解

    面试题 63:二叉搜索树的第k个结点 题目:给定一颗二叉搜索树,请找出其中的第k大的结点.例如, 5 / \ 3 7 /\ /\ 2 4 6 8 (见下面的图1) 中,按结点数值大小顺序第三个结点的值 ...

  3. 剑指offer面试题14(Java版):调整数组顺序使奇数位于偶数的前面

    题目:输入一个整数数组.实现一个函数来调整该数组中数字的顺序.使得全部奇数位于数组的前半部分.全部偶数位于数组的后半部分. 1.基本实现: 假设不考虑时间复杂度,最简单的思路应该是从头扫描这个数组,每 ...

  4. 剑指Offer:面试题15——链表中倒数第k个结点(java实现)

    问题描述 输入一个链表,输出该链表中倒数第k个结点.(尾结点是倒数第一个) 结点定义如下: public class ListNode { int val; ListNode next = null; ...

  5. 【Java】 剑指offer(22) 链表中倒数第k个结点

    正文 本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入一个链表,输出该链表中倒数第k个结点.为了符合大多数人的 ...

  6. 【剑指Offer面试题】 九度OJ1517:链表中倒数第k个结点

    鲁棒性是指程序可以推断输入是否符合规范要求,并对不和要求的输入予以 合理的处理. 题目链接地址: http://ac.jobdu.com/problem.php?pid=1517 题目1517:链表中 ...

  7. 【剑指Offer面试题】 九度OJ1371:最小的K个数

    题目链接地址: http://ac.jobdu.com/problem.php?pid=1371 题目1371:最小的K个数 时间限制:1 秒内存限制:32 兆特殊判题:否提交:5938解决:1265 ...

  8. 剑指Offer编程题(Java实现)——链表中倒数第k个结点

    题目描述 输入一个链表,输出该链表中倒数第k个结点. 注意: 该题目不可以用先反转链表再输出第k个结点的方式,因为反转链表会改变该结点的next指向 思路一 使用栈Stack倒序存储,顺序pop第k个 ...

  9. 剑指Offer:链表中倒数第k个结点【22】

    剑指Offer:链表中倒数第k个结点[22] 题目描述 输入一个链表,输出该链表中倒数第k个结点. 解题思考 我们定义两个指针L和R,R事先移动K-1个位置,然后两者同时往后移动直到遇到R的下个节点为 ...

随机推荐

  1. 关于JVM内存模型,GC策略以及类加载器的思考

    JVM内存模型 Sun在2006年将Oracle JDK开源最终形成了Open JDK项目,两者在绝大部分的代码上都保持一致.JVM的内存模型是围绕着原子性(操作有且仅有一个结果).可见性(racin ...

  2. [LUOGU] [NOIP2017] P3960 列队

    题目描述 Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n \times mn×m 名学生,方阵的行 ...

  3. MySQL字符集设定与查询

    一.字符集设定 MySQL数据库允许对服务器.数据库.数据表.数据列级别的字符集作出互不影响的设定. 1.对服务器字符集设定是通过配置文件中选项character-set-server 设置,如 ch ...

  4. Go:channel

    一.channel 在 Go 语言里,不仅可以使用原子函数和互斥锁来保证对共享资源的安全访问以及消除竞争状态,还可以使用 channel,通过发送和接收需要共享的资源,在 goroutine 之间做同 ...

  5. matlab自定义函数的五种表示(前2种重点)

    1.命令文件/函数文件+函数文件:多个M文件 2.函数文件+子函数:一个M文件 3. inline:无需M文件 4.符号表达式+subs方式:无需M文件 5.字符串+subs方式:无需M文件 第一种: ...

  6. 2018 GDCPC 省赛总结

    第二次参加省赛了,对比上年连STL都不会的acm入门者来说, 今年是接触acm的第二年. 首先要说的是今年的省赛比上年人数多了很多, 闭幕式200多支队伍坐满了整个礼堂还要站着不少人,所以今年的竞争其 ...

  7. [mvc]MVC_Model

    1,Model的职责: Model只负责与数据处理相关的工作. 2,开发Model的基本观念 采用ORM信息访问技术开发 ORM是将结构化的关系型数据,映射成面向对象模型.对于EF来说,就是关系型数据 ...

  8. shelve -- 用来持久化任意的Python对象

    这几天接触了Python中的shelve这个module,感觉比pickle用起来更简单一些,它也是一个用来持久化Python对象的简单工具.当我们写程序的时候如果不想用关系数据库那么重量级的东东去存 ...

  9. ajax跨域访问总结

    1,jsonp的使用 就是script引用别的站点js,利用回调把内容传给这个js。 a需要引入b,在页面上引入b的js,里面有b的函数,在a中执行,就能拿到json了。 程序B中test.js的代码 ...

  10. javascript:与获取鼠标位置有关的属性

    javascript并没有mouse对象,获取鼠标坐标要靠强大的event对象。 我们通过监听document的mousemove,就可以实时获得鼠标位置。 但是!!event中和鼠标相关的属性太多了 ...