参考自:《剑指Offer——名企面试官精讲典型编程题》
题目:在O(1)时间删除链表结点
给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。
主要思路:
分三种情况:
1.要删除的结点不是尾结点:将要删除的结点替换成它的下一个结点。
2.链表只有一个结点,即头结点就是要删除的结点:直接将头结点设置为null。
3.要删除的结点是尾结点:找到要删除的结点的前一个结点,将找到的该结点的下一结点设置为null。
关键点:结点替换,特殊结点(头结点和尾结点)
时间复杂度:平均为O(1)
public class DeleteNodeInList {
public static void main(String[] args) {
int[] data = {3, 4, 5, 7};
ListNode pHead = LinkedListData.generateDataByArray(data);
//5
ListNode deletedNode5 = pHead.next.next;
//7
ListNode deletedNode7 = pHead.next.next.next;
ListNode result = deleteNode(pHead, pHead);
while (result != null) {
System.out.println(result.val);
result = result.next;
}
}
private static ListNode deleteNode(ListNode head, ListNode deletedNode) {
if (head == null || deletedNode == null) {
return null;
}
//删除的结点不是尾结点
if (deletedNode.next != null) {
//将要删除的结点替换成它的下一个结点
ListNode nextNode = deletedNode.next;
deletedNode.val = nextNode.val;
deletedNode.next = nextNode.next;
}
//链表只有一个结点,即头结点就是要删除的结点
else if (head.val == deletedNode.val) {
head = null;
}
//删除的结点是尾结点
else {
ListNode pNode = head;
//找到要删除的结点的前一个结点
while (pNode.next.val != deletedNode.val) {
pNode = pNode.next;
}
pNode.next = null;
}
return head;
}
}
class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
class LinkedListData {
/**
* 根据数组生成链表
*
* @param data
* @return
*/
public static ListNode GenerateDataByArray(int[] data) {
ListNode head = new ListNode(data[0]);
ListNode currentNode = head;
for (int i = 1; i < data.length; i++) {
ListNode next = new ListNode(data[i]);
currentNode.next = next;
currentNode = next;
}
return head;
}
}