面试题 13:在 O( 1)时间删除链表结点
题目:给定单向链表的头指针和一个结点指针,定义一个函数在 O(1)时间删除该结点。
思路
这道题的考点是单链表的单向性。想要删除给定的结点node,其前驱结点为pNode,后继结点为nNode。正常思路是:将pNode的next值由node改为nNode(也就是node.next)。然后node对象赋值为空。用代码表示:
… //初始信息
pNode.next = nNode;
node = null;
这是删除node结点的一般思路,但是在这道题中我们不知道node的前驱结点pNode,如果想要得到,只能通过遍历寻找得到pNode,和题目要求O(1)时间复杂度不符合,但是node的后继结点nNode是可以在O(1)时间复杂度内找到的。所以我们的思路是,放弃寻找pNode,转而将nNode的值存储到node结点内,然后删除nNode结点;这个办法等价于直接删除node结点。
图片表示:
代码
package swordOffer;
/**
* 面试题 13:在 O( 1)时间删除链表结点
* 题目:给定单向链表的头指针和一个结点指针,定义一个函数在 O(1)时间删除该结点。
*
* @author Stephen Huge
*
*/
public class Ex13DelNodeInO_1 {
public static void main(String[] args) throws Exception {
ListNode d = new ListNode(4);
ListNode c = new ListNode(3, d);
ListNode b = new ListNode(2, c);
ListNode a = new ListNode(1, b);
ListNode head = a;
Ex13DelNodeInO_1 dnio = new Ex13DelNodeInO_1();
int data = dnio.delNodeInO_1(head, d);
System.out.println(data);
}
public int delNodeInO_1(ListNode head, ListNode delNode) throws Exception {
if(head == null || delNode == null) {
throw new Exception("输入有误,删除失败");
}
if(delNode == head) { //删除头指针
head = delNode.next;
int hTemp = delNode.data;
delNode = null;
return hTemp;
}
if(delNode.next == null) { //删除尾指针
int tTemp = delNode.data;
delNode = null;
return tTemp;
}
int mTemp = delNode.data;
delNode.data = delNode.next.data;
delNode.next = delNode.next.next;
return mTemp;
}
// public class ListNode {
// public int data;
// public ListNode next;
//
// public ListNode() {
// }
// public ListNode(int data) {
// this.data = data;
// }
// public ListNode(int data, ListNode next) {
// this.data = data;
// this.next = next;
// }
// }
}
代码逻辑也没不太难,在考虑了链表为null以及删除头结点和尾结点的特殊情况后,其它情况均按照上面思路处理。