您的位置:首页 > 职场人生

剑指offer 面试题13 在o(1)时间删除链表结点

2017-05-26 11:14 531 查看

剑指offer 面试题13 在o(1)时间删除链表结点

题目:

给定单项链表的头指针和一个结点指针,定义一个函数在 O(1) 时间删除该节点。

链表结点与函数定义如下:

package algorithm.foroffer.top20;

/**
* Created by liyazhou on 2017/5/25.
* 面试题13:在 O(1) 时间删除链表结点
*
* 题目:
*      给定单项链表的头指针和一个结点指针,定义一个函数在 O(1) 时间删除该节点。
*      链表结点与函数定义如下:
*
* 问题:
*      1. 快速定位结点位置
*
* 思路:
*      1. 一般思路是,删除单向链表的一个结点,需要获取该结点的前驱节点,但时间复杂度是 O(n),不可行
*      2. 要删除单向链表的一个结点,可以将其后继结点复制到当前结点,并删除该后继结点即可
*         存在特殊情况,
*              如果单向链表只有一个结点,则将头指针赋值为空既可以
*              如果要删除的结点位于单向链表的末尾,则需要顺序遍历所有的结点,直到倒数第二个结点,把其后继结点设置为空
*/

class Node{
int value;
Node next;
}

public class Test13 {

/**
* 删除单向链表中的某个结点
* @param head 单向链表头结点
* @param deleteNode 链表中的某个结点,由该方法的调用者控制,此方法在 O(1)时间无法检验该结点是否属于链表
* @return
*/
public static Node deleteNode(Node head, Node deleteNode){
if (head == null || deleteNode == null) return head;

// 只有一个结点的单向链表,由于已经保证两个结点都属于链表,所以此处两者相同
if (head.next == null) return null;

// 有两个及以上结点的单向链表,且要删除的结点位于单向链表末尾
if (deleteNode.next == null){
Node preNode;
// 找到最后倒数第二个结点
for (preNode = head; preNode.next.next != null; preNode = preNode.next);
preNode.next = null;
return head;
}

// 要删除的节点在单链表中间位置
Node nextNode = deleteNode.next;  // 获取待删除结点的后继结点
deleteNode.value = nextNode.value; // 将待删除结点的后继结点,复制到待删除结点
deleteNode.next = nextNode.next;  // 将待删除结点的后继结点设置为其后继结点的后继结点

return head;
}

public static void main(String[] args){
Node head = new Node();
head.value = 0;
Node tmpNode = head;
Node deleteNode = null;
for (int i = 1; i < 10; i++){
Node currNode = new Node();
currNode.value = i;

tmpNode.next = currNode;
tmpNode = currNode;

if (i == 4) deleteNode = currNode;
}

Node link = Test13.deleteNode(head, deleteNode);
for(Node currNode = link; currNode != null && currNode.next != null; currNode = currNode.next)
System.out.println(String.format("currNode = %d, nextNode = %d", currNode.value, currNode.next.value));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: