在单链表和双链表中删除倒数第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 ...
随机推荐
- jenkins+github持续集成中的坑
1.前言 刚开始开发自己的独立博客的时候,每次发布都要手动打包,上传服务器,杀tomcat进程,重启,来回这么重复性工作,很快就有点不耐烦了.如果能自动化的东西,就绝不要手动了,所以自己搭建了个持续集 ...
- android.app.Activity 的介绍
发现当前Android的资料不是非常多,并且对于Activity的介绍也非常少.所以把官方文档的android.app.Activity的介绍翻译了一下,增加了一些自己的理解.各位假设认为我自己理解的 ...
- 原来你是这样的JAVA[01]-基础一瞥
1.Java是什么呢? Java不仅是一门语言,而且是一个完整的平台,有一个庞大的库,其中包含了很多可重用的代码和一个提供安全性.跨操作系统的可移植性以及自动垃圾收集等服务的执行环境. 2.JDK 和 ...
- Mac环境下实现alias重命名命令(永久生效)
Mac环境下实现alias重命名命令 iOS Dev在使用Xcode完成代码编写后,可能需要上传至第三方分发应用给测试人员进行相关测试,比如蒲公英.FIR. 效率较高的上传方式是借助于Fastlane ...
- seleniumPO模式
一.框架目录结构 二.代码 2.1page层代码 package com.mianshui.page; import org.openqa.selenium.WebElement; import or ...
- iOS 判断数组array中是否包含元素a,取出a在array中的下标+数组方法详解
目前找到来4个解决办法,第三个尤为简单方便 NSArray * arr = @["]; //是否包含 "]) { NSInteger index = [arr indexOfObj ...
- C# VS2010结合SQL Server 2008数据库编程实现方法
SQL Server 数据库在C#编程中经常用到,如何实现在具体项目中数据库和具体应用的结合是我们经常遇到的问题,我们这次主要针对如何使用SQL Server 数据库展开,下面是具体的操作以及简单的代 ...
- Zip4J最简单用法
package com.chentao.MicroMessage.bussiness; import java.io.File; import java.util.ArrayList; import ...
- echarts异步数据加载(在下拉框选择事件中异步更新数据)
接触echarts 大半年了,从不会到熟练也做过不少的图表,隔了一段时间没使用这玩意,好多东西真心容易忘了.在接触echarts这期间也没有总结什么东西,今天我就来总结一下如何在echart中异步加载 ...
- ArcGIS API for JavaScript 4.2学习笔记[14] 弹窗的位置、为弹窗添加元素
这一节我们来看看弹窗的位置和弹窗上能放什么. 先一句话总结: 位置:可以随便(点击时出现或者一直固定在某个位置),也可以指定位置 能放什么:四种,文字.媒体(图片等).表格.附件. [Part I 位 ...


