删除链表的节点
题目:在O(1)的时间内删除链表的某一指定节点。给定单向链表的头指针和一个节点指针,定义一个函数在O(1)的时间内删除该节点。
举例:a->b->c->d->e,删除c,结果:a->b->d->e
第一步:先将c节点的下一个节点的值赋值给c节点
a->b->d->d->e
第二步:将赋值后新节点d(原c节点的位置)的指针=原节点d的指针,这样新节点d就指向了原d节点指向的节点。
a->b->d->e
另外注意只有一个节点,和头尾节点删除的临界情况。
注意大坑
1.题中并未说明是比较值,还是比较对象(即内存),业务上常规情况都是比较值,如果是比较值,那就需要限制链表中不能有重复值。
2.我选择的是比较内存,依旧存在问题,如果不使用构建链表的元素对象,那么就达不到删除元素的目的。也是测试过程中才发现。记录一下
3.总结:学习删除链表的思路,问清楚面试官要求,熟悉链表结构
废话不多说了,上代码。
选择使用值做对比。
/**
* 找到目标节点的前一个节点,将他的下一个节点替换成目标节点的下一个节点
* 重点:链表中不能存在重复的值
* @param head 头节点
* @param val 目标节点的值
* @return
*/
public static LinkedNode deleteNode(LinkedNode head, Integer val) {
//常规判空
if(head == null || val == null){
return null;
}
//如果是头节点,则直接返回头节点的下一个节点。
if(head.getValue() == val){
return head.getNextNode();
}
//目标节点的前一个节点,初始值设为头节点
LinkedNode pre = head;
//当前节点,初始值设置为头节点的下一个节点
LinkedNode cur = head.getNextNode();
//当前节点不为空且当前节点的值不等于目标节点的值
while(cur != null && cur.getValue() != val) {
//将当前节点赋值给pre;
pre = cur;
//将当前节点的下一个节点赋值给cur
cur = cur.getNextNode();
}
//此时pre为目标节点的前一个节点
if(cur != null) {
pre.setNextNode(cur.getNextNode());
}
return head;
}
选用内存对象对比
public class DeletOneNode {
public static LinkedNode deletOneNode(LinkedNode root,LinkedNode targetNode){
//常规判空
if(root == null || targetNode ==null){
return null;
}
//如果删除的节点不是尾节点
if(targetNode.getNextNode()!=null){
//获取到目标节点的下一个节点targetNextNode,使用targetNextNode替换掉targetNode
LinkedNode targetNextNode = targetNode.getNextNode();
//先替换值
targetNode.setValue(targetNextNode.getValue());
//再替换指针
targetNode.setNextNode(targetNextNode.getNextNode());
return root;
}
//头节点等于目标节点,且只有一个节点。
if(root == targetNode){
return null;
}
LinkedNode nextNode = root;
//尾节点处理
while(nextNode!=null){
nextNode = nextNode.getNextNode();
if(nextNode.getNextNode()==targetNode){
nextNode.setNextNode(null);
break;
}
}
return root;
}
public static void printNode(LinkedNode node){
while(node!=null){
System.out.println(node.getValue());
node = node.getNextNode();
}
}
public static void main(String[] args) {
LinkedNode node4 = new LinkedNode(4);
LinkedNode node3 = new LinkedNode(3,node4);
LinkedNode node2 = new LinkedNode(2,node3);
LinkedNode node1 = new LinkedNode(1,node2);
//测试
LinkedNode newRootTest= DeletOneNode.deletOneNode(node1,node1);
DeletOneNode.printNode(newRootTest);
}
}
数据结构:
public class LinkedNode {
private int value;
private LinkedNode nextNode;
public LinkedNode(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public LinkedNode getNextNode() {
return nextNode;
}
public LinkedNode(int value, LinkedNode nextNode) {
this.value = value;
this.nextNode = nextNode;
}
public void setValue(int value) {
this.value = value;
}
public void setNextNode(LinkedNode nextNode) {
this.nextNode = nextNode;
}
}