方式一:删除特定结点
示例:
输入:head = [1,2,6,3,4,5,6],data = 6
输出:[1,2,3,4,5]
说明:删除节点node时,必须知道前驱pre节点和后继next结点,然后让pre.nextNode=node.nextNode,这样node就脱离了链表,会在某个时刻被gc回收掉。
思路:1.创建一个虚拟表头node,使其nextNode指向headNode,再创建一个新的结点:Node cur = node。
2.开始循环链表寻找特定结点,使用cur.nextNode.data来判断是否为特定节点。
3.如果找到目标元素,使用cur.nextNode=cur.nextNode.nextNode来删除。
4.如果不是目标元素,使用cur=cur.nextNode。
5.注意返回值应该为:node.next。
具体实现的代码封装在方法removeNode()中,如下:
//移除指定数据的节点,data表示要删除结点的数据,headNode为头结点
private static Node removeNode(int data,Node headNode) {
//创建一个虚拟节点node,指向headNode
Node node =new Node(0);
node.nextNode = headNode;
Node curNode = node;
while(curNode.nextNode!=null) {
if(curNode.nextNode.data == data) {
curNode.nextNode = curNode.nextNode.nextNode;
}else {
curNode = curNode.nextNode;
}
}
return node.nextNode;
}
方式二:删除倒数第n个结点
示例:
输入:head=[1,2,3,4,5],n=2
输出:[1,2,3,5]
思路:先遍历一遍链表获得链表的长度L,然后再次遍历删除位置为L-n+1的结点 。
1.创建一个虚拟表头node,使其nextNode指向headNode,再创建一个新的结点:Node curNode = node。
2.开始循环链表将curNode指向第L-n+1个结点的前驱结点,然后使用curNode.next=curNode.nextNode.nextNode删除结点。
具体代码入下:
//删除倒数第n个结点
private static Node removeEndNode(int n,Node headNode) {
Node node = new Node(0);
node.nextNode = headNode;
Node curNode = node;
int m = linkedListLength(headNode);
//删除第i个结点
int i = m - n + 1;
for(int k=1;k<i;k++) {
curNode=curNode.nextNode;
}
curNode.nextNode = curNode.nextNode.nextNode;
return node.nextNode;
}
//遍历链表获得链表的总长度L
private static int linkedListLength(Node headNode) {
int m=1;
Node curNode = headNode;
while(curNode.nextNode != null) {
curNode=curNode.nextNode;
m++;
}
return m;
}
方式三:删除重复元素
(1)重复元素保留一个
前提:链表为升序。
示例:
输入:head=[1,1,2,3,3]
输出:[1,2,3]
思路: 由于链表已经是排序好的,因此重复的元素是连续的,对链表进行遍历,查询重复即可删除重复的元素。
具体代码如下:
//删除重复的结点,链表为有序
private static Node deleteDuplicates(Node headNode) {
Node node = headNode;
if(headNode == null) {
return headNode;
}
while(node.nextNode != null) {
if(node.data == node.nextNode.data) {
node.nextNode = node.nextNode.nextNode;
}else {
node = node.nextNode;
}
}
return headNode;
}
(2)重复元素都不要
前提:链表为有序。
示例:
输入:head=[1,2,3,3,4,4,5]
输出:[1,2,5]
思路:链表直接对curNode.nextNode以及curNode.nextNode.nextNode两个node进行比较就行了,这里需要注意两个node可能为空,需要判断。
具体代码如下所示:
//删除重复的结点全部删除,链表为有序
private static Node deleteDuplicates(Node headNode) {
Node node = new Node(0);
node.nextNode = headNode;
Node curNode = node;
if(headNode == null) {
return headNode;
}
while(curNode.nextNode != null && curNode.nextNode.nextNode!=null) {
if(curNode.nextNode.data == curNode.nextNode.nextNode.data) {
int x = curNode.nextNode.data;
while(curNode.nextNode != null && curNode.nextNode.data==x) {
curNode.nextNode = curNode.nextNode.nextNode;
}
}else {
curNode = curNode.nextNode;
}
}
return node.nextNode;
}