程序员代码面试指南(左程云)读书笔记 2-1
第二章
在单链表和双链表中删除倒数第K个节点
题目:分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点。
要求:
如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1)
单链表删除倒数第k个数
public class Node {
public int value;
public Node next;
public Node(int data){
this.value=data;
}
}
package com.chen.homework;
public class Last_K_Node {
public static void main(String[] args) {
Node node=new Node(8);
Node no=new Node(2);
Node no2=new Node(3);
node.next=no;
no.next=no2;
System.out.println(node.value+"---"+node.next.value+"---"+node.next.next.value);
Node c= deleteLastNode1(node,3);
System.out.println(c.value+"--"+c.next.value);
DoubleNode d=new DoubleNode(2);
DoubleNode d2=new DoubleNode(3);
DoubleNode d3=new DoubleNode(4);
DoubleNode d4=new DoubleNode(5);
DoubleNode d5=new DoubleNode(6);
d.next=d2;
d2.next=d3;
d3.next=d4;
d4.next=d5;
d5.last=d4;
d4.last=d3;
d3.last=d2;
d2.last=d;
System.out.println(d.next.value);
DoubleNode dd=removeLast(d,4);
System.out.println(dd.next.value);
}
static Node deleteLastNode1(Node head,int k){
if(head==null || k<1){
return head;
}
Node cur=head;
while(cur!=null){
k--;
cur=cur.next;
}
if(k==0){
head=head.next;
}
if(k<0){
cur=head;
while(k++!=0){
cur=cur.next;
}
cur.next=cur.next.next;
}
return head;
}
/*
* 两个变量记录位置 pre和last都指向头节点,pre先走到k-1个节点,然后pre和last一起走,当pre走到末尾时就是倒数第K个节点,然后
* 将k-1的next指向k的next,相当于删除k节点
* */
public Node deleteLastNode2(Node head,int k){
if(head==null || k<=0){
return null;
}
Node pre=head;
Node last=head;
for(int i=1;i<k;i++){
if(pre.next!=null){
pre=pre.next;
}else{
return null;
}
}
while(pre.next!=null){
pre=pre.next;
last.next=last.next.next;
}
return head;
}
/*
* 双链表删除倒数第K个节点
* */
public static DoubleNode removeLast(DoubleNode head,int k){
if(head==null||k<1){
return head;
}
DoubleNode cur=head;
while(cur!=null){
k--;
cur=cur.next;
}
if(k==0){
head=head.next;
head.last=null;
}
if(k<0){
cur=head;
while(++k!=0){
cur=cur.next;
}
DoubleNode newNext=cur.next.next;
cur.next=newNext;
if(newNext!=null){
newNext.last=cur;
}
}
return head;
}
}