您的位置:首页 > 编程语言

简单编程题目连载(二)

2017-01-03 23:17 225 查看
在单链表和双链表中删除倒数第K个节点

题目:分别实现两个函数,一个可以删除单链表中倒数第k个节点,另一个可以删除双链表中倒数第k个节点。

要求:如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1)。

思路:

如果链表为空,或者k小于1,那么无需进行处理,因为属于无效输入,直接返回即可。

当链表的长度大于1时,从链表头开始,遍历每个元素,每遍历一个元素,令k-1,直到遍历结束。

如果k>=1,说明k值大于整个链表的长度,没有可以进行删除的元素。

如果k=0,说明k值等于链表的长度,相当于删除链表的头节点,令head=head.next;即可。

如果k<0,说明要删除的元素处于链表中间。删除链表中间的元素需要进行两步操作:找到删除元素的前一个节点;将该元素指向待删除元素的下一个节点。

此时进行第二次遍历,每经过一个节点,k+1,直到k=0为止。

因为第N-K个节点为目标节点的前一个节点。换个想法,而当k<0时,x+k=0,x=-k,互补的关系,这个第x个节点就是目标节点的前一个节点。

class Node{
int value;
Node next;
public Node(int data){
this.value = data;
}
}

class test{
public Node removeLastKthNode(Node head,int lastKth){
if(head == null || lastKth < 1){
return head;
}
Node cur = head;
while(cur != null){
cur = cur.next;
lastKth--;
}
if(lastKth == 0){
return head.next;
}
if(lastKth < 0){
cur = head;
while(++lastKth != 0){
cur = cur.next;
}
cur.next = cur.next.next;
}
return head;
}
}


对于双向链表而言前面的步骤是一样的,不同在于不光要处理指向后,还要处理指向前。

class DoubleNode{
public int value;
public DoubleNode last;
public DoubleNode next;
public DoubleNode(int data){
this.value = data;
}
}

public DoubleNode removeLastKthNode(DoubleNode head,int lastKth){
if(head == null || lastKth < 1){
return head;
}
DoubleNode cur = head;
while(cur != null){
cur = cur.next;
lastKth--;
}
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;
head.next = newNext;
if(newNext != null){
newNext.last = cur;
}
}
return head;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编程 单链表 链表