我有删除当前节点的实现。条件是:我们只知道当前节点。
这样做的方法是:
如下所示:
public class ListNode<T> {
private ListNode<T> next = null;
private T data;
public ListNode(T data) {
this.data = data;
}
/*
* Add a new node after the current node
* Time Complexity: O(1)
*/
public void add(T data) {
ListNode<T> newNode = new ListNode<T>(data);
newNode.setNext(this.getNext());
this.setNext(newNode);
}
/*
* Delete the current node
* Time Complexity: O(1)
*/
public T delete() {
ListNode<T> nextNode = next;
if (nextNode == null) { /* The current node is the last node. */
return null;
}
T nextData = nextNode.getData();
this.setData(nextData);
this.setNext(nextNode.getNext());
return nextData;
}
/* getters and setters */
}
但是,有一个例外:如果当前节点是列表中的最后一个节点,这将不起作用。
我可以想办法解决这个问题:
TerminatorNode
,它始终位于链表的末尾。我想知道:如何实现它?或者,这种节点应该是什么类型的class
?
编辑1:
为了清楚起见,我的问题是:我怎么能总是删除当前节点,即使它是链表上的最后一个节点?我想有一个TerminalNode
,它总是在链表的末尾,它只代表链表结束。 (它类似于字符串末尾的\0
。)然后可以使用时间为O(1)的相同方法始终删除其他正常节点。
编辑2: 这是关于破解编码面试的一些声明:
例如,您可以考虑将节点标记为虚拟。
这是什么意思?
答案 0 :(得分:0)
为简单起见,我们将LinkedNode
表示为data
,将next
表示为null
。我们还假设终端节点是结束列表的唯一有效方式。
private boolean isTerminalNode() {
return this.getData() == null && this.getNext() == null;
}
如果列表的末尾始终是终端节点,则可以删除除终端之外的任何节点。
/*
* Delete the current node Time Complexity: O(1)
*/
public T delete() {
if (this.isTerminalNode()) {
// Cannot delete the terminal node.
// Either throw an IllegalArgumentException or return silently
return null;
}
ListNode<T> nextNode = this.getNext();
this.setData(nextNode.getData());
this.setNext(nextNode.getNext());
return this.getData();
}
但是,现在我们在节点之后添加时可能会遇到类似的问题。
/*
* Add a new node after the current node Time Complexity: O(1)
*/
public void add(T data) {
if (this.isTerminalNode()) {
// Cannot add a node after the terminal node.
// Either throw an IllegalArgumentException, return silently, or add
// the data at the current position and create a new terminal node.
throw new IllegalArgumentException("Cannot add a node after the terminal node");
}
ListNode<T> newNode = new ListNode<T>(data);
newNode.setNext(this.getNext());
this.setNext(newNode);
}