在单链表和双链表中删除倒数第k个结点
题目:
分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点。
要求:
如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1)。
解答:
让链表从头走到尾,每移动一步,就让K值减一,
示例:
第一种情况:
链表走到结尾时,如果K值大于0,说明不用调整链表,因为链表根本没有倒数第K个节点,此时将原链表直接返回即可;
第二种情况:
链表走到结尾时,如果K值等于0,说明链表倒数第K个节点就是头结点,此时直接返回head.next,相当于删除了头结点。
第三种情况:(当链表走到结尾时,当K的值小于零时,)
K< 0 时的处理方法:
![]()
链表长度为N,要删除倒数第K个节点,那么倒数第K个节点的前一个结点就是第N-K个节点。在第一次遍历之后,K的值变为了K-N。第二次遍历时,K的值不断加1.加到0就停止遍历,所在的位置就是第N-K个节点的位置。
public class Problem02_RemoveLastKthNode {
// 单链表
public static class Node {
public int value;
public Node next;
public Node (int data){
this.value = data;
}
}
// 双链表
public static class DoubleNode{
public int value;
public DoubleNode last;
public DoubleNode next;
public DoubleNode (int data) {
this.value = data;
}
}
// 删除单链表中倒数第K个结点
/* 1. 异常情况考虑:---- 链表为空,K值<1, 返回头结点
* 2. 其他(链表非空,K值>0) 策略:从头结点开始往后k--
* 2.1. 到达链表尾部时(cur = null), k>0, 则不存在K结点;
* 2.2. 到达链表尾部时(cur = null), k=0, 则头结点head就是K结点;
* 2.3. 到达链表尾部时(cur = null), k<0, 则需要找到删除K结点的前一个结点;
* 详情:
* 重新从头结点开始,每移动一步,就让K值加1;
* 当k=0时,移动停止,移动到的结点就是要删除的结点的前一个结点
*/
public static Node removeLastKthNode(Node head, int lastKth){
if (head == null || lastKth < 1){
return head;
}
Node cur = head;
while(cur != null) {
lastKth--;
cur = cur.next;
}
if (lastKth == 0){
head = head.next;
}
if (lastKth < 0){
cur = head;
while( ++lastKth != 0){
cur = cur.next;
}
cur.next = cur.next.next;
}
return head;
}
// 删除双链表中倒数第K个结点(同单链表,注意last指针的重连即可)
public static DoubleNode removeLastKthNode(DoubleNode head, int lastKth){
if (head == null || lastKth < 1){
return head;
}
DoubleNode cur = head;
while(cur != null){
lastKth--;
cur = cur.next;
}
if(lastKth == 0){
head = head.next;
head.last = null;
}
if (lastKth < 0){
cur = head;
while(++lastKth != 0){
cur = cur.next;
}
DoubleNode newNext = cur.next.next;
cur.next = newNext;
if (newNext != null) {
newNext.last = cur;
}
}
return head;
}
// 打印链表值函数
public static void printLinkedList(Node head) {
System.out.println("Linked list: ");
while(head != null){
System.out.println(head.value + " ");
head = head.next;
}
System.out.println();
}
public static void printDoubleLinkedList(DoubleNode head){
System.out.println("DoubleLinked list: ");
DoubleNode end = null;
while (head != null) {
System.out.println(head.value + " ");
end = head;
head= head.next;
}
System.out.println("**********");
while(end != null) {
System.out.println(end.value + " ");
end = end.last;
}
System.out.println();
}
public static void main(String[] args) {
Node head1 = new Node(1);
head1.next = new Node(2);
head1.next.next = new Node(3);
head1.next.next.next = new Node(4);
head1.next.next.next.next = new Node(5);
head1.next.next.next.next.next = new Node(6);
printLinkedList(head1);
head1 = removeLastKthNode(head1, 3);
// head1 = removeLastKthNode(head1, 6);
// head1 = removeLastKthNode(head1, 7);
printLinkedList(head1);
DoubleNode head2 = new DoubleNode(1);
head2.next = new DoubleNode(2);
head2.next.last = head2;
head2.next.next = new DoubleNode(3);
head2.next.next.last = head2.next;
head2.next.next.next = new DoubleNode(4);
head2.next.next.next.last = head2.next.next;
head2.next.next.next.next = new DoubleNode(5);
head2.next.next.next.next.last = head2.next.next.next;
head2.next.next.next.next.next = new DoubleNode(6);
head2.next.next.next.next.next.last = head2.next.next.next.next;
printDoubleLinkedList(head2);
head2 = removeLastKthNode(head2, 3);
// head2 = removeLastKthNode(head2, 6);
// head2 = removeLastKthNode(head2, 7);
printDoubleLinkedList(head2);
}
}
结果:
Linked list:
1
2
3
4
5
6 Linked list:
1
2
3
5
6 DoubleLinked list:
1
2
3
4
5
6
**********
6
5
4
3
2
1 DoubleLinked list:
1
2
3
5
6
**********
6
5
3
2
1
在单链表和双链表中删除倒数第k个结点的更多相关文章
- [算法]在单链表和双链表中删除倒数第k个结点
题目: 分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点. 要求: 如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1). 解答: 让链表从头 ...
- 在单链表和双链表中删除倒数第K个节点
[说明]: 本文是左程云老师所著的<程序员面试代码指南>第二章中“在单链表和双链表中删除倒数第K个节点”这一题目的C++复现. 本文只包含问题描述.C++代码的实现以及简单的思路,不包含解 ...
- 《程序员代码面试指南》第二章 链表问题 在单链表和双链表中删除倒数第K个节点
题目 在单链表和双链表中删除倒数第K个节点 java代码 /** * @Description:在单链表和双链表中删除倒数第K个节点 * @Author: lizhouwei * @CreateDat ...
- 链表中获取倒数第K个结点
/* * 链表中查找倒数第K个结点.cpp * * Created on: 2018年5月1日 * Author: soyo */ #include<iostream> using nam ...
- 链表中删除倒数第K个节点
问题描述 分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点. 问题分析与解决 从问题当中,我们只能得到一个链表和要删除的第K个节点的信息,于是就有以下思路:如 ...
- 链表实现比较高效的删除倒数第k项
最近写链表不太顺,无限的段错误.今天中午写的链表删除倒数第k项,用的带尾节点的双向链表,感觉已经把效率提到最高了,还是超时,改了很多方法都不行,最 终决定看博客,发现原来是审题错了,阳历给的是以-1结 ...
- 链表中的倒数第k个结点
题目描述 输入一个链表,输出该链表中倒数第k个结点. 基本思想:定义两个指针a,b分别指向头节点, a指针先向前走k-1步(注意:因为倒数节点是从倒数第一个结点开始的,而不是零),然后a指针和b指 ...
- 【剑指offer】链表中的倒数第k个结点
输入一个链表,输出该链表中倒数第k个结点. 分析: 定义两个结点p1和p2都指向头节点,p1先走k-1步,然后p1和p2一起走,当p1走到链表尾部时,p2指向的结点就是倒数第k个结点 遍历一遍链表即可 ...
- 算法总结之 在单链表和双链表中删除倒数第k个节点
分别实现两个函数,一个可以删除单链表中倒数第k个节点,另一个可以删除双链表中倒数第k个节点 思路: 如果链表为空,或者k<1 参数无效 除此之外 让链表从头开始走到尾,每移动一步,就让k的值减1 ...
随机推荐
- logstash 向elasticsearch写入数据,怎样指定多个数据template
之前在配置从logstash写数据到elasticsearch时,指定单个数据模板没有问题.可是在配置多个数据模板时候,总是不成功,后来找了非常多资料,最终找到解决的方法,就是要多加一个配置项: te ...
- 【Jquery系列】JqGrid参数详解
1 概述 本篇文章主要与大家分享JqGrid插件参数问题. 2 参数详解 2.1 初始化参数 2.2 ColModel参数 3 json数据 jqGrid可支持的数据类型:xml.jso ...
- Java中流-----个人总结心得
流 字符流 字节流 缓冲区 数据流---用于传输数据.IO流---Input/Output流.数据从外部流向程序---输入流:数据从程序流向外部的时候--输出流.读取一个文件---数据从文件流向程序- ...
- SSM学习(一)搭建基础框架
不知不自觉,工作也两年多了,由于公司一直用的是ssh框架,所以所学也一直是ssh.直到有一天,服务器被攻击,tomcat目录下总有莫名其妙的一些文件,这些文件通过远程ftp下载了一些病毒和木马,服务器 ...
- Photoshop 无法打开某些JPEG文件的成因
最近想把QQ相册里的一些照片整理修复一下,所以下载了一些到本地,然后用PS CC 2018打开,结果PS告诉我"无法完成请求,因为程序错误".试了Win10系统自带的看图软件,能够 ...
- GitLab版本管理工具
第1章 GitLab管理 1.1 版本控制系统 版本控制系统(version control system)是记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统.版本控制系统不仅可以应用于 ...
- 数据库的SQL优化
1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. (因为在条件查询条件添加索引,会直接被检索到列,会非常的快速) 2.应尽量避免在 wher ...
- wincc flexable变量组态
1.变量分类 2.变量组态练习 3.变量组态之前新建一个设备连接取名connect 3.tag1组态bool类型,双击变量弹出下面窗口,具体如下图所示connect表示外部变量 4.组态tag2 5. ...
- android操作系统在itop4412开发板上的烧写
ITOP4412启动模式: 1.EMMC启动模式:拨码开关1-3为011 2.SD卡启动模式:拨码开关1-3为100uboot:初始化内存控制器,访问存储器,把操作系统内核从存储器读取出来放到内存中, ...
- js变量提升与函数提升
在es6之前,js语言并没有块级作用域,即{}形成的作用域,只有全局作用域和函数作用域,所谓的提升,即是将该变量的声明或者函数的声明提升,举个例子 console.log(global); //und ...


