剑指Offer 面试题18:删除链表节点 Java代码实现
2017-11-16 22:08
796 查看
题目:在O(1)时间内删除链表节点。
给定单向链表头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点。
这儿采用有头结点的单链表结构,头结点的存在是为了方便操作,针对单链表来说,如果带头结点的话,头指针指向头结点,头结点指向首结点;如果不带头结点的话,头指针指向首结点,如果进行插入和删除操作,必须要注意是否是在链表头进行,要分情况处理,而带头结点的不用分情况,比较方便。
一般情况下,删除单链表中的第k个节点,需要遍历链表找到对应节点的上一节点,然后删除第k个节点,这样的时间复杂度自然是O(n)。这儿情况比较特殊,方法参数给了我们需要删除的节点引用,就可以采用一种新的思路删除该节点。具体而言,就是把待删除节点的下一节点数据域复制到待删除节点,然后删除下一节点。整个过程实际上就是删除了待删除节点的内容,时间复杂度为O(1)。当然,尾节点没有下一节点,我们还是需要遍历,不过平均复杂度仍然是O(1)。
节点类代码如下,就是一个value域,一个next域。里面的函数是打印输出链表,方便看结果。
public class ListNode {
int value;
ListNode next;
public static void printStr(ListNode head) {
if (head == null)
return;
ListNode pNode = head.next;
while (pNode != null) {
if(pNode.next==null){
System.out.print(pNode.value);
System.out.println();
pNode = pNode.next;
}else{
System.out.print(pNode.value);
System.out.print("->");
pNode = pNode.next;
}
}
}
}
主要方法代码:
public static void deleteNode(ListNode pHead,ListNode toBeDelete){
if(pHead==null||toBeDelete==null)
return;
//要删除的节点不是尾节点
if(toBeDelete.next!=null){
ListNode pNext=toBeDelete.next;
toBeDelete.value=pNext.value;
toBeDelete.next=pNext.next;
pNext=null;
}else if(pHead==toBeDelete){
//链表只有一个节点
pHead=null;
}else{
//链表有多个节点,要删除尾节点
//只有这种情况下时间复杂度为O(n)
ListNode pNode=pHead;
while(pNode.next!=toBeDelete){
pNode=pNode.next;
}
pNode.next=null;
toBeDelete=null;
}
}
上面代码中必须要求我们输入的参数,节点toBeDelete必须在链表中。受限于O(1)的要求,这儿没有做检查。
测试代码如下:
1->2->3->4
1->3->4
给定单向链表头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点。
这儿采用有头结点的单链表结构,头结点的存在是为了方便操作,针对单链表来说,如果带头结点的话,头指针指向头结点,头结点指向首结点;如果不带头结点的话,头指针指向首结点,如果进行插入和删除操作,必须要注意是否是在链表头进行,要分情况处理,而带头结点的不用分情况,比较方便。
一般情况下,删除单链表中的第k个节点,需要遍历链表找到对应节点的上一节点,然后删除第k个节点,这样的时间复杂度自然是O(n)。这儿情况比较特殊,方法参数给了我们需要删除的节点引用,就可以采用一种新的思路删除该节点。具体而言,就是把待删除节点的下一节点数据域复制到待删除节点,然后删除下一节点。整个过程实际上就是删除了待删除节点的内容,时间复杂度为O(1)。当然,尾节点没有下一节点,我们还是需要遍历,不过平均复杂度仍然是O(1)。
节点类代码如下,就是一个value域,一个next域。里面的函数是打印输出链表,方便看结果。
public class ListNode {
int value;
ListNode next;
public static void printStr(ListNode head) {
if (head == null)
return;
ListNode pNode = head.next;
while (pNode != null) {
if(pNode.next==null){
System.out.print(pNode.value);
System.out.println();
pNode = pNode.next;
}else{
System.out.print(pNode.value);
System.out.print("->");
pNode = pNode.next;
}
}
}
}
主要方法代码:
public static void deleteNode(ListNode pHead,ListNode toBeDelete){
if(pHead==null||toBeDelete==null)
return;
//要删除的节点不是尾节点
if(toBeDelete.next!=null){
ListNode pNext=toBeDelete.next;
toBeDelete.value=pNext.value;
toBeDelete.next=pNext.next;
pNext=null;
}else if(pHead==toBeDelete){
//链表只有一个节点
pHead=null;
}else{
//链表有多个节点,要删除尾节点
//只有这种情况下时间复杂度为O(n)
ListNode pNode=pHead;
while(pNode.next!=toBeDelete){
pNode=pNode.next;
}
pNode.next=null;
toBeDelete=null;
}
}
上面代码中必须要求我们输入的参数,节点toBeDelete必须在链表中。受限于O(1)的要求,这儿没有做检查。
测试代码如下:
public static void main(String[] args) { ListNode head = new ListNode(); ListNode node1 = new ListNode(); ListNode node2 = new ListNode(); ListNode node3 = new ListNode(); ListNode node4 = new ListNode(); //采有头结点的链表,数据域不用,指针域指向第一个有数据的链表节点 head.next = node1; node1.value = 1; node1.next = node2; node2.value = 2; node2.next = node3; node3.value = 3; node3.next = node4; node4.value=4; node4.next = null; ListNode.printStr(head); // deleteNode(head, node1); // deleteNode(head, node4); deleteNode(head, node2); ListNode.printStr(head); }输出如下:
1->2->3->4
1->3->4
相关文章推荐
- 剑指offer面试题18:删除链表的节点-java
- 剑指offer面试题56 链表中环的入口节点(java实现)
- 剑指Offer面试题57:删除重复链表 Java实现
- 剑指Offer 面试题24:反转链表 Java代码实现
- 剑指Offer 面试题25:合并两个排序的链表(递归+非递归) Java代码实现
- 剑指Offer面试题13(java版):在O(1)时间删除链表节点
- 剑指Offer面试题56:链表中环的入口节点 Java实现
- 剑指offer--面试题13:在O(1)时间删除链表结点--Java实现
- 【剑指offer】面试题18:删除链表中重复的节点
- 剑指offer--面试题13:在O(1)时间删除链表结点--Java实现
- 剑指Offer面试题18:删除链表的节点
- 剑指offer 面试题16 反转链表-Java实现
- 剑指offer编程题Java实现——面试题13在O(1)时间内删除链表节点
- 剑指Offer--面试题18:数的子结构--Java实现
- 剑指offer----链表中环的入口节点----java实现
- 剑指offer|面试题5:从尾到头打印链表(Java实现)
- 剑指offer面试题java实现之题5:逆序打印链表
- 剑指offer 面试题17 合并两个排序的链表-Java实现
- 剑指Offer:面试题16——反转链表(java实现)
- 剑指Offer(java版):在O(1)时间删除链表节点