题解 | #从单向链表中删除指定值的节点#
从单向链表中删除指定值的节点
https://www.nowcoder.com/practice/f96cd47e812842269058d483a11ced4f
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) { // 注意 while 处理多个 case
String str = in.nextLine(); //获得输入
String[] strs = str.split(" "); //按空白拆分,方便处理
int n = Integer.parseInt(strs[0]); //总结点数
int firstValue = Integer.parseInt(strs[1]); //头节点值
int aimValue = Integer.parseInt(strs[strs.length - 1]); //目标节点值
LinkList ll = new LinkList(); //自定义链表
ll.add(firstValue); //插入头节点
for (int i = 2; i < strs.length - 1; i += 2) { //插入其他节点
ll.addNext(Integer.parseInt(strs[i]), Integer.parseInt(strs[i + 1]));
}
if (ll.removeNode(aimValue)) { //删除目标节点
ll.printNodeValue();
}
// System.out.println(a + b);
}
}
public static void readLinkList(LinkList lastNode) {
}
}
class LinkList { //自定义链表类
int size = 0; //链表长度
Node headNode; //头节点
Node tailNode; //尾节点
LinkList() { //无参构造
}
static class Node { //内部节点类
int value; //节点值
Node pre; //头指针
Node curr; //尾指针
Node(int value, Node pre, Node curr) { //构造
this.value = value;
this.pre = pre;
this.curr = curr;
}
Node() {
}
}
public boolean add(int val, int index) { //指定下标插入
Node newNode = new Node(val, null, null); //新节点
if (size == 0) { //判空
headNode = newNode;
tailNode = newNode;
size++;
return true;
} else if (index < 0 || index > size + 2) { //判下标范围
return false;
} else if (index == 1) { //头节点位置直接插入
newNode.curr = headNode;
headNode.pre = newNode;
headNode = newNode;
size++;
return true;
} else if (index == size + 1) { //尾节点位置直接插入
newNode.pre = tailNode;
tailNode.curr = newNode;
tailNode = newNode;
size++;
return true;
} else { //中间位置
Node preNode = null; //前一个
Node currNode = headNode;//后一个(注意前后是挨着的,preNode->currNode)
for (int i = 2; i <= index; i++) { //获得指定下标位置的节点currNode
preNode = currNode;
currNode = currNode.curr;
}
newNode.pre = preNode;
newNode.curr = currNode;
preNode.curr = newNode;
currNode.pre = newNode;//插入操作
size++; //长度增加
return true;
}
}
public void add(int val) { //尾插法插入节点
Node newNode = new Node(val, null, null);
if (size == 0) { //判空
headNode = newNode;
tailNode = newNode;
size++;
} else {
newNode.pre = tailNode;
tailNode.curr = newNode;
tailNode = newNode;
size++;
}
}
public boolean addNext(int val, int pre) { //题中指定插入方法,插入指定值的节点后面
Node newNode = new Node(val, null, null);
if (size == 0) { //判空
return false;
}
Node preNode = null;
Node currNode = headNode;
for (int i = 0; i < size; i++) { //遍历链表找指定值节点
if (currNode.value == pre) { //找到后处理
newNode.pre = currNode;
if (currNode.curr == null) { //判断是否为尾节点
currNode.curr = newNode;
size++;
return true;
} else { //其他情况
newNode.curr = currNode.curr;
currNode.curr = newNode;
currNode = newNode;
size++;
return true;
}
}
preNode = currNode;
currNode = currNode.curr;
}
return false;
}
public void printNodeValue() { //遍历链表并打印节点
Node preNode = null;
Node currNode = headNode;
while (currNode.curr != null) {
System.out.print(currNode.value + " ");
preNode = currNode;
currNode = currNode.curr;
}
System.out.print(currNode.value + "");
}
public boolean removeNode(int val) { //删除节点
Node preNode = null;
Node currNode = headNode;
for (int i = 0; i < size; i++) { //遍历链表找节点
if (currNode.value == val) { //找到处理
if (currNode.pre == null) { //头节点
headNode = currNode.curr;
size--;
return true;
} else if (currNode.curr == null) { //尾节点
currNode.pre.curr = null;
size--;
return true;
} else { //其他情况
preNode.curr = currNode.curr;
currNode.curr.pre = preNode;
size--;
return true;
}
}
preNode = currNode;
currNode = currNode.curr;
}
return false;
}
}
手搓链表
查看25道真题和解析