剑指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的下个节点为 ...
随机推荐
- 448. Find All Numbers Disappeared in an Array@python
Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and ot ...
- 四、StaticList 和 DynamicList
1.StaticList类模板 StaticList的设计要点:类模板 使用原生数组作为顺序存储空间 使用模板参数决定数组大小 template <typename T, int N> c ...
- SQL的几种连接
1. 内连接 结果: 从左表中取出每一条记录,去右表中与所有的记录进行匹配: 匹配必须是某个条件是左表中与右表中相同,才会保留结果,否则不保留: 1.等值连接:在连接条件中使用等于号(=)运算符比较被 ...
- [LUOGU] P3469 [POI2008]BLO-Blockade
https://www.luogu.org/problemnew/show/P3469 求无向图分别删去每个点后不连通的点对数. 首先,对于任何一个点,它本身删了,就会和剩下的n-1个点不连通,点对是 ...
- Ubuntu配置SSH服务器
SSH 为 Secure Shell 的缩写,由 IETF 的网络小组(Network Working Group)所制定:SSH 为建立在应用层和传输层基础上的安全协议.SSH 是目前较可靠,专为远 ...
- Python_编程题集_002_菱形
2.编写程序实现: n=5,输出: * *** ***** *** * n=6,输出: * *** ***** ***** *** * n为任意大于1的正整数. 解: #思路: # 第一步:判断行数, ...
- python_time和datetime模块
time和datatime模块 时间相关的操作,时间有三种表示方式: 时间戳 1970年1月1日之后的秒,即:time.time() 格式化的字符串 2019-1-1 ...
- python基础——5(元组、字典、集合)
上节复习: # 数字类型 # int:py3|py2 long:py2 # float: 3.14 # complex(5, 4) => 5 + 4j num = 12345678901234 ...
- Leetcode 312.戳气球
戳气球 有 n 个气球,编号为0 到 n-1,每个气球上都标有一个数字,这些数字存在数组 nums 中. 现在要求你戳破所有的气球.每当你戳破一个气球 i 时,你可以获得 nums[left] * n ...
- Android ScaleDrawable
顾名思义,Android ScaleDrawable实现一个drawable的缩放.写一个例子. 一个线性布局,垂直放几个ImageView,然后依次缩放若干个ScaleDrawable. 布局文件: ...