6.查找单链表中的倒数第k个结点
普通思路:先将整个链表从头到尾遍历一次,计算出链表的长度size,得到链表的长度之后,就好办了,直接输出第(size-k)个节点就可以了(注意链表为空,k
为0,k为1,k大于链表中节点个数时的情况)。时间复杂度为O(n),大概思路如下:
public int findLastNode(int index) {
// index代表的是倒数第index的那个结点
// 第一次遍历,得到链表的长度size
if (head == null) {
return -1;
}
int size = 0;
current = head;
while (current != null) {
size++;
current = current.next;
}
// 第二次遍历,输出倒数第index个结点的数据
current = head;
for (int i = 0; i < size - index; i++) {
current = current.next;
}
return current.data;
}
如果面试官不允许你遍历链表的长度,该怎么做呢?接下来就是。
改进思路:(这种思路在其他题目中也有应用)
这里需要声明两个指针:即两个结点型的变量first和second,首先让first和second都指向第一个结点,然后让second结点往后挪k-1个位置,此时first和second就间隔了k-1个位置,然后整体向后移动这两个节点,直到second节点走到最后一个结点的时候,此时first节点所指向的位置就是倒数第k个节点的位置。时间复杂度为O(n)
代码实现:(初版)
public Node findLastNode(Node head, int index) {
if (head == null) {
return null;
}
Node first = head;
Node second = head;
// 让second结点往后挪index个位置
for (int i = 0; i < index; i++) {
second = second.next;
}
// 让first和second结点整体向后移动,直到second结点为Null
while (second != null) {
first = first.next;
second = second.next;
}
// 当second结点为空的时候,此时first指向的结点就是我们要找的结点
return first;
}
代码实现:(最终版)
(考虑k大于链表中结点个数时的情况时,抛出异常)
上面的代码中,看似已经实现了功能,其实还不够健壮:
要注意k等于0的情况;
如果k大于链表中节点个数时,就会报空指针异常,所以这里需要做一下判断。
核心代码如下:
public Node findLastNode(Node head, int k) {
if (k == 0 || head == null) {
return null;
}
Node first = head;
Node second = head;
// 让second结点往后挪k-1个位置
for (int i = 0; i < k - 1; i++) {
System.out.println("i的值是" + i);
second = second.next;
if (second == null) {
// 说明k的值已经大于链表的长度了 //throw new NullPointerException("链表的长度小于" + k); //我们自己抛出异常,给用户以提示
return null;
}
}
// 让first和second结点整体向后移动,直到second走到最后一个结点
while (second.next != null) {
first = first.next;
second = second.next;
}
// 当second结点走到最后一个节点的时候,此时first指向的结点就是我们要找的结点
return first;
}
测试代码:
public static void main(String[] args) {
LinkList list = new LinkList();
// 向LinkList中添加数据
for (int i = ; i < ; i++) {
list.add(i);
}
list.print(list.head);// 从head节点开始遍历输出
System.out.print(list.getLength(list.head));
System.out.print("\r\n");
// System.out.print(list.findLastNode(10));
System.out.print(list.findLastNode(list.head,7).getData());
System.out.print("\r\n");
System.out.print(list.findMidNode(list.head).data);
}
6.查找单链表中的倒数第k个结点的更多相关文章
- 链表习题(8)-寻找单链表中数据域大小为k的结点,并与前一结点交换,如果前一结点存在的情况下
/*寻找单链表中数据域大小为k的结点,并与前一结点交换,如果前一结点存在的情况下*/ /* 算法思想:定义两个指针,pre指向前驱结点,p指向当前结点,当p->data == k的时候,交换 p ...
- 在单链表和双链表中删除倒数第k个结点
题目: 分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点. 要求: 如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1). 解答: 让链表从头 ...
- [算法]在单链表和双链表中删除倒数第k个结点
题目: 分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点. 要求: 如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1). 解答: 让链表从头 ...
- 链表中获取倒数第K个结点
/* * 链表中查找倒数第K个结点.cpp * * Created on: 2018年5月1日 * Author: soyo */ #include<iostream> using nam ...
- 链表中的倒数第k个结点
题目描述 输入一个链表,输出该链表中倒数第k个结点. 基本思想:定义两个指针a,b分别指向头节点, a指针先向前走k-1步(注意:因为倒数节点是从倒数第一个结点开始的,而不是零),然后a指针和b指 ...
- 【剑指offer】链表中的倒数第k个结点
输入一个链表,输出该链表中倒数第k个结点. 分析: 定义两个结点p1和p2都指向头节点,p1先走k-1步,然后p1和p2一起走,当p1走到链表尾部时,p2指向的结点就是倒数第k个结点 遍历一遍链表即可 ...
- 在单链表和双链表中删除倒数第K个节点
[说明]: 本文是左程云老师所著的<程序员面试代码指南>第二章中“在单链表和双链表中删除倒数第K个节点”这一题目的C++复现. 本文只包含问题描述.C++代码的实现以及简单的思路,不包含解 ...
- 《程序员代码面试指南》第二章 链表问题 在单链表和双链表中删除倒数第K个节点
题目 在单链表和双链表中删除倒数第K个节点 java代码 /** * @Description:在单链表和双链表中删除倒数第K个节点 * @Author: lizhouwei * @CreateDat ...
- python经典算法面试题1.5:如何找出单链表中的倒数第K个元素
本题目摘自<Python程序员面试算法宝典>,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中. [微软笔试题] 难度系数:⭐⭐⭐ 考察频率:⭐⭐⭐⭐⭐ 题目描 ...
随机推荐
- JS实现文本框和文本域获取焦点focus()时,光标在本文的末尾
<!-- <input type="text" id="test1" name="test1" value="test ...
- 在PL/SQL中调用存储过程--oracle
在oracle10中写好了存储过程,代码如下: CREATE OR REPLACE Procedure Proc_Insert ( sName in varchar2, sAge in int, sE ...
- 【MLE】最大似然估计Maximum Likelihood Estimation
模型已定,参数未知 已知某个随机样本满足某种概率分布,但是其中具体的参数不清楚,参数估计就是通过若干次试验,观察其结果,利用结果推出参数的大概值.最大似然估计是建立在这样的思想上:已知某个参数能使这个 ...
- Python(四)之Python流程控制(if、while、for)
Python流程控制 if测试: if 条件测试表达式: 组合条件测试: x and y:与运算 x or y:或运算 not x:非运算 while: break:跳出最内层的循环 continue ...
- JAVA-JSP内置对象之out对象进行页面输出
相关资料:<21天学通Java Web开发> out对象 out对象进行页面输出1.通过out对象的print()方法和println()方法进行页而输出.2.不同的println()方法 ...
- C#学习笔记(10)——再谈委托,不同国家问候的例子
说明(2017-6-14 09:08:38): 1. 首先是一个简单的委托 (1)命名空间下定义一个委托MyDel: public delegate void MyDel(string name); ...
- 初学SSH 配置+错误总结
初学java web 一上手就接触ssh,前段时间,断断续续配置好了ssh,今天从Hibernate入手开始学习.先总结今天遇到的问题. 配置链接的是sqlserver的数据库,首先是下载了一个jdb ...
- 如何在线程中获取spring 管理的bean
转载自:https://my.oschina.net/skyline520/blog/181158?fromerr=GjtR6Wec spring xml中定义 <!--spring 工具类-- ...
- CentOS6.5 安装Python 的依赖包
1.CentOS6.5 安装Python 的依赖包 yum groupinstall "Development tools"yum install zlib-devel bzip2 ...
- systemd&systemctl
systemd is a system and service manager for Linux operating systems. When run as first process on bo ...