剑指Offer面试题15(Java版):链表中倒数第K个结点
题目: 输入一个链表。输出该链表中倒数第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个结点的更多相关文章
- 《剑指offer》— JavaScript(14)链表中倒数第k个结点
链表中倒数第k个结点 题目描述 输入一个链表,输出该链表中倒数第k个结点. 思路 两个指针,先让第一个指针和第二个指针都指向头结点,然后再让第一个指正走(k-1)步,到达第k个节点: 然后两个指针同时 ...
- C++版 - 剑指offer 面试题63:二叉搜索树的第k个结点(二叉树中序遍历的应用) 题解
面试题 63:二叉搜索树的第k个结点 题目:给定一颗二叉搜索树,请找出其中的第k大的结点.例如, 5 / \ 3 7 /\ /\ 2 4 6 8 (见下面的图1) 中,按结点数值大小顺序第三个结点的值 ...
- 剑指offer面试题14(Java版):调整数组顺序使奇数位于偶数的前面
题目:输入一个整数数组.实现一个函数来调整该数组中数字的顺序.使得全部奇数位于数组的前半部分.全部偶数位于数组的后半部分. 1.基本实现: 假设不考虑时间复杂度,最简单的思路应该是从头扫描这个数组,每 ...
- 剑指Offer:面试题15——链表中倒数第k个结点(java实现)
问题描述 输入一个链表,输出该链表中倒数第k个结点.(尾结点是倒数第一个) 结点定义如下: public class ListNode { int val; ListNode next = null; ...
- 【Java】 剑指offer(22) 链表中倒数第k个结点
正文 本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 输入一个链表,输出该链表中倒数第k个结点.为了符合大多数人的 ...
- 【剑指Offer面试题】 九度OJ1517:链表中倒数第k个结点
鲁棒性是指程序可以推断输入是否符合规范要求,并对不和要求的输入予以 合理的处理. 题目链接地址: http://ac.jobdu.com/problem.php?pid=1517 题目1517:链表中 ...
- 【剑指Offer面试题】 九度OJ1371:最小的K个数
题目链接地址: http://ac.jobdu.com/problem.php?pid=1371 题目1371:最小的K个数 时间限制:1 秒内存限制:32 兆特殊判题:否提交:5938解决:1265 ...
- 剑指Offer编程题(Java实现)——链表中倒数第k个结点
题目描述 输入一个链表,输出该链表中倒数第k个结点. 注意: 该题目不可以用先反转链表再输出第k个结点的方式,因为反转链表会改变该结点的next指向 思路一 使用栈Stack倒序存储,顺序pop第k个 ...
- 剑指Offer:链表中倒数第k个结点【22】
剑指Offer:链表中倒数第k个结点[22] 题目描述 输入一个链表,输出该链表中倒数第k个结点. 解题思考 我们定义两个指针L和R,R事先移动K-1个位置,然后两者同时往后移动直到遇到R的下个节点为 ...
随机推荐
- 分享点干货(此this非彼this)this的详细解读
在javascript编程中,this关键字经常让初学者感到迷惑,这里,针对此this根据查阅的资料和个人的理解分享一下,纯手打,大神勿喷. 首先先说一下this的指向,大致可以分为以下四种. 1.作 ...
- ICPC-Beijing 2006 狼抓兔子
题目描述 题解: 裸的最小割. 但是最大流跑不过去怎么办? 转变一下,既然最大流是一条左下<->右上的通路,我们可以把图划分为若干区域, 最后找左下到右上的最短路就行了. 代码: #inc ...
- [LUOGU] P3871 [TJOI2010]中位数
题目描述 给定一个由N个元素组成的整数序列,现在有两种操作: 1 add a 在该序列的最后添加一个整数a,组成长度为N + 1的整数序列 2 mid 输出当前序列的中位数 中位数是指将一个序列按照从 ...
- Python Socket详细介绍
Socket 类型 套接字格式: socket(family,type[,protocal]) 使用给定的地址族.套接字类型.协议编号(默认为0)来创建套接字. socket类型 描述 socket. ...
- Ubuntu 和 centos7 服务的启动
Ubuntu 下: /etc/init.d/nginx start | stop | reload Centos7下: service nginx start | stop | reload
- Python旅途——文件操作
Python--文件操作 1.理解文件操作 可能有的时候有人会在想为什么要对文件进行操作,无论对于文件还是网络之间的交互,我们都是建立在数据之上的,如果我们没有数据,那么很多的事情也就不能够成立,比如 ...
- Android开发——短信电话拦截/接听电话
1.短信拦截 首先需要声明的是,Android4.4版本以上,如果想做到短信拦截,必须成为default sms,把所有短信相关的功能都包揽了,然后再做短信拦截.但这种做法,适配性和兼容性的工作是非常 ...
- 【Ajax 3】JavaScript封装Ajax
导读:上一篇博客简单介绍了一下对Ajax中的核心对象XMLHttpRequest的封装.那么为了方便对Ajax的应用,我们还需要进一步的对Ajax的基本功能进行下一步的封装,不得不说的是早就有人专门写 ...
- 生产环境下lnmp的权限说明
https://www.cnblogs.com/zrp2013/p/4183546.html 有关权限说明:-rwxrw-r‐-1 root root 1213 Feb 2 09:39 50.html ...
- 【分块+树状数组】codechef November Challenge 2014 .Chef and Churu
https://www.codechef.com/problems/FNCS [题意] [思路] 把n个函数分成√n块,预处理出每块中各个点(n个)被块中函数(√n个)覆盖的次数 查询时求前缀和,对于 ...