题目: 输入一个链表。输出该链表中倒数第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. Visual C++中error spawning cl.exe错误的两种解决方法.

    可能很多人在安装VC 6.0后有过点击“Compile”或者“Build”后被出现的 “Compiling... ,Error spawning cl.exe”错误提示给郁闷过.很多人的 选择是重装, ...

  2. [JOYOI] 1071 LCIS

    拖了好久的LCIS f[i][j]表示a串前i个,b串以b[j]结尾的LCIS长度. 转移时考虑a[i]和b[j]是否相等,如果不等: 那么既然是以j结尾,说明a串前i-1位有一个字符和b匹配了,所以 ...

  3. [CF] 986 A. Fair

    http://codeforces.com/problemset/problem/986/A n个点的无向连通图,每个点有一个属性,求每个点到s个不同属性点的最短距离 依稀记得那天晚上我和Menteu ...

  4. Django框架基础知识06-模型基础

    1.数据库的连接配置 django 连接mysql的配置流程: 安装 pymysql pip install pymysql 创建数据库用户 有创建数据库权限的用户 创建数据库 crm 修改配置 se ...

  5. MySQL 存储 utf8mb4

    1.如果是阿里云数据库 a.控制台->修改参数character_set_server参数为UTF8mb4 b.设置库的字符集为UTF8mb4 2.如果是自己mysql服务器 [client] ...

  6. OO博客作业

    第一次多项式的作业感觉还行,同时用c和java写的话也算是一个从c到java的过渡,也算是有了对 java的初步认识,之后的电梯作业出血了一些小BUG,比如有些情况考虑不完善之类的,也算是对面向对象有 ...

  7. linux 在当前目录下查找一个,或者多个文件

    1.find ./ -name "y*" 查找以y开头的文件. find ./ -name "*sql*" 查找包含 sql 的文件名 2.查找redis su ...

  8. 大数据学习——flume安装部署

    1.Flume的安装非常简单,只需要解压即可,当然,前提是已有hadoop环境 上传安装包到数据源所在节点上 然后解压  tar -zxvf apache-flume-1.6.0-bin.tar.gz ...

  9. BZOJ1916: [Usaco2010 Open]冲浪

    n<=50000个点m<=150000的带边权DAG,保证1入度0,n出度0,其他点入度出度均不为0,求:从一号点开始到n,期间有可能K<=10次随机选边走,最坏情况下总边权多少. ...

  10. SQL中distinct的用法(四种示例分析)

    在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只 用它来返回不重复记录的条数,而不是用它来返回不重记录的 ...