数据结构和算法之单向链表二:获取倒数第K个节点
我们在做算法的时候或多或少都会遇到这样的问题,那就是我们需要获取某一个数据集的倒数或者正数第几个数据。那么今天我们来看一下这个问题,怎么去获取倒数第K个节点。我们拿到这个问题的时候自然而然会想到我们让链表从末尾开始next K-1 次不就是第K-1个节点了么,但是必须要注意一点,这是单向链表。那么这时候的解决思路或许就会出现分歧,大多数人都会想到我们遍历一下链表,获取链表的长度,然后再减去 K 长度的节点,那么我们这个链表的最后一个节点就是原链表的倒数第K个节点:我们看一下实现代码:
/**
* 获取倒数第K个节点的数据
* @param index
* @return
*/
public int getDtae(int index){
//对整个链表进行遍历
int size = 0;
Node current = head;//head是头结点
while(current!=null){
size++;
current = current.next;
}
current = head;
//向后遍历size-K获取倒数第K个节点
for(int i = 0;i < size - index;i++){
current = current.next;
}
return current.date;
}
我们可以发现,这段代码可不可以实现我们需要的功能,当然可以。那么问题来了,如果我们要是输入的index大于链表的长度或者说链表自身就是一个空链表,那么,我们这段代码会不会出现问题。或者当我们的index等于0的时候,又会不会出现问题,正常来说我们将倒数都是从倒数第一开始,倒数零是不是就没有意义,那么这一段代码还够不够强壮。这个问题或许我们稍微有一点良好的编程思想都会想到,我们留到最后解决。下面我们需要思考的是怎么在遍历一边链表的情况下就获取到上面的数据。我们可不可以定义两个节点first和second,他们同时指向head头结点。我们先把第二个节点向后移动index-1步,这时first和second是不是就相距k,我们再把两个节点同时向后移动,当second到达链表尾端的时候,是不是就可以说first的位置就是我们需要的倒数第K个节点。代码如下:
/**
* 获取倒数第K个节点的数据
* @param index
* @return
*/
public int getDtae(int index){
//定义两个节点指向head
Node first = head;
Node second = head;
//把第二个节点向后移动k-1步
for(int i = 0;i < index - 1;i++){
second = second.next;
}
//再把两个节点同时向后移动,直到second到达尾端位置
while(second!=null){
first = first.next;
second = second.next;
}
return first.date;
}
我们可以看到这一段代码是不是就已经实现了。但是还是那个问题,一段代码的强壮型在于它在处理特殊事件时候的能力,别让整个程序崩溃。接下来我们进行以下操作,避免我们所说的三个问题,index等于0,index超过了链表的长度,链表是空链表/** * 获取倒数第K个节点的数据 * @param index
* @return
*/
public int getDtae(int index){
//判断index是否为零或者是小于零的不合法数据
if(index <= 0 || head == null){
//抛出空指针异常
throw new NullPointerException();
}
//定义两个节点指向head
Node first = head;
Node second = head;
//第二个节点向后移动K-1步
for(int i = 0;i < index -1;i++){
//判断second是否为空
second = second.next;
if(second==null){
throw new NullPointerException();
}
} //两个节点向后移动直到链表的尾端 while(second!=null){ first = first.next; second = second.next; } return first.date; }
我们可以看到在开始直接判断k等于0的情况,我们在第二个节点向后移动的时候直接判断他是否为空,如果链表为空,那么刚开始second自然为空,如果index大于链表长度,在之后next的过程中,自然second也会产生空的情况。这就完美解决了上面提到的三个情况,index等于零,index大于链表长度,链表为空的情况。我们在进行测试的时候可以通过我上一篇博客对一个链表插入数据,然后再进行功能测试,获取链表的首尾中三个节点数据,在进行特殊测试的时候可以输入上面的三种情况就是测试。
通过以上问题我们还可以思考一个事情,如果我们需要得到中间节点,但是只允许遍历一次的情况下我们应该怎么去实现:
public int getMiddle(){
//判断链表是否为空
if(head == null){
throw new NullpointerExpection();
}
//定义两个节点同时指向首节点
Node first = head;
Node second = head;
//将第二个节点向后移动两步,第一个节点向后移动一步,直到second到达尾端
while( second.next != null){
first = first.next;
second = second.next.next;
}
return first.date;
}
我们需要注意的是这段代码有一点缺陷,那就是我们的链表长度如果是偶数的话,那么我们获取到的中间值就是 N/2 + 1的节点,与我们的计算会相差一位,不过这不是重点,重要的是我们需要体会里面的思想。
if(second==null){
throw new NullPointerException();
}
数据结构和算法之单向链表二:获取倒数第K个节点的更多相关文章
- 算法总结之 在单链表和双链表中删除倒数第k个节点
分别实现两个函数,一个可以删除单链表中倒数第k个节点,另一个可以删除双链表中倒数第k个节点 思路: 如果链表为空,或者k<1 参数无效 除此之外 让链表从头开始走到尾,每移动一步,就让k的值减1 ...
- 在单链表和双链表中删除倒数第K个节点
[说明]: 本文是左程云老师所著的<程序员面试代码指南>第二章中“在单链表和双链表中删除倒数第K个节点”这一题目的C++复现. 本文只包含问题描述.C++代码的实现以及简单的思路,不包含解 ...
- 《程序员代码面试指南》第二章 链表问题 在单链表和双链表中删除倒数第K个节点
题目 在单链表和双链表中删除倒数第K个节点 java代码 /** * @Description:在单链表和双链表中删除倒数第K个节点 * @Author: lizhouwei * @CreateDat ...
- 链表问题----删除倒数第K个节点
在单链表和双链表中删除倒数第K个节点 分别实现两个函数,一个可以删除单链表中的倒数第K个节点,一个可以删除双链表中的倒数第k 个节点,要求时间复杂度是 O(N),空间复杂度是 O(1). [解析] 基 ...
- 链表中获取倒数第K个结点
/* * 链表中查找倒数第K个结点.cpp * * Created on: 2018年5月1日 * Author: soyo */ #include<iostream> using nam ...
- 面试题 02.02. [链表][双指针]返回倒数第 k 个节点
面试题 02.02. 返回倒数第 k 个节点 方法一:使用外部空间 // 执行用时: 1 ms , 在所有 Java 提交中击败了 16.75% 的用户 // 内存消耗: 36.8 MB , 在所有 ...
- 1.求链表中的倒数第K个节点
注意事项:1.要是K大于链表长度怎么办? 2.k<=0怎么办? ListNode* FindR_Kth(ListNode* p_head, unsigned int k) 2 {//找到链表的倒 ...
- 链表中删除倒数第K个节点
问题描述 分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点. 问题分析与解决 从问题当中,我们只能得到一个链表和要删除的第K个节点的信息,于是就有以下思路:如 ...
- 线性数据结构案例1 —— 单向链表中获取倒数k个节点
一.介绍 先遍历整个链表获取链表长度length,然后通过 (length-index) 方式得到我们想要节点在链表中的位置. 二.代码 public Node findLastIndexNode( ...
随机推荐
- Vim技能修炼教程(9) - 缓冲区和标签页
缓冲区 上一节我们学习了窗口相关的命令,其实多窗口的最大功能在于存放多个不同的缓冲区. 文件载入内存之后,我们操作的其实是缓冲区.:write命令就是将缓冲区写回文件的目的. 查看内存中的缓冲区 通过 ...
- RxJava 1.x 笔记:变换型操作符
在写这几篇 RxJava 笔记时,发现官方文档很久都没有更新啊. 一些前辈两年前写的学习笔记内容跟现在也基本一致,RxJava 2.x 的文档也基本没有,不知道是不是缺实习生. 本文内容为 RxJav ...
- 【剑指offer】10A--求裴波那切数列的第n项,C++实现
#本文是牛客网<剑指offer>刷题笔记 1.题目 写入一个函数,输入n,输出裴波那切数列的第n项 2.思路 递归--时间和空间复杂度高 循环--时间和空间复杂度低,通过循环迭代计算第n项 ...
- 基于 od 窗口的anti
虽然 odadvance 这类的插件 , 使用驱动将 od 的窗口 进行 隐藏,使用enumwindow ,无法枚举到od的窗口, 但是依然可以 使用r3 的方法 , 对od 窗口检测 之后可以使用 ...
- postman简单使用
postman百度网盘下载地址:https://pan.baidu.com/s/1nuO2CGT 下载压缩后 打开chrome输入chrome://extensions/ 把文件拖到浏览器中 启动po ...
- 《DSP using MATLAB》示例Example 8.12
%% ------------------------------------------------------------------------ %% Output Info about thi ...
- RF自定义系统关键字
如果您准备学习Python,船长在这里给大家推荐几个学习Python的好地方: 1.廖雪峰官网 http://www.liaoxuefeng.com/wiki/001374738125095c95 ...
- Ecel 粘贴图片并调整大小,移到底层
Sub Click() ActiveSheet.Pictures.Paste.Select Selection.ShapeRange.ScaleWidth 1.4, msoTrueSelection. ...
- ldo的一些参数理解
psrr是衡量ldo抑制外来信号噪声的能力,而内部噪声是由基准电压和误差放大器引入的.通常器件手册说的输出噪声指的就是内部噪声. ldo的暂态响应也是一个重要指标
- 使用npm install报错- operation not permitted解决
原文:https://blog.csdn.net/weixin_41715295/article/details/79508104 这几天使用npm install时一直报错-4048 operati ...