持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第21天,点击查看活动详情
题目
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
解题思路
关键词:链表;相同节点值
关键信息:递归求解;链式结构
删除相同节点值链表结构一般采用递归方法求解:遍历整个链表移除链表相应节点即可。
递归解法
public ListNode removeElements(ListNode head, int val) {
// 递归
if(head == null) return null;
head.next = removeElements(head.next,val);
if(head.val == val){
return head.next;
}else{
return head;
}
}
插入头节点解法
如果不使用递归解法如果要遍历链表必然会找不到当前头节点了,在原链表头部插入一个节点可以帮助定位原链表头。
- 新建一个头节点执行链表头部。
- 循环遍历(起始点从head开始。
- 循环体中对节点值判断:等于对应值则移除该节点并指向下一个;不等于移位到下一个节点。
- 跳出循环后最后以新建节点为指针输出结果链表。
public ListNode removeElements(ListNode head, int val) {
if(head == null) return null;
ListNode newHead = new ListNode(0);
newHead.next = head;
ListNode temp = newHead;
while(temp.next != null){ // 起始从head开始遍历
if(temp.next.val == val){ // 判断是否等于指定值
temp.next = temp.next.next; //
}else{
temp = temp.next;
}
}
return newHead.next;
}
PS:
1.为什么不直接移动newHead而新建一个temp?newHead作为指针指向下一个数就是节点头因此添加副本来移动。
2.为什么不使用head进行循环移动?移动head可能会导致newHead.next不在执行head了。
双循环解法
通过插入头节点解法思路可以再实现另外一种解法。
- 首先处理头节点为空或者值相等的情况。
- 处理完头节点特殊情况后增加head副本,通过副本循环移除符合条件的节点。
- 最终输出head即可。
public ListNode removeElements(ListNode head, int val) {
while(head !=null && head.val == val){
head = head.next;
}
if(head == null) return null;
ListNode temp = head;
while(temp.next != null){
if(temp.next.val == val){
temp.next = temp.next.next;
}else{
temp = temp.next;
}
}
return head;
}
参考
- 来源:力扣(LeetCode)