文章目录
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。
返回删除后的链表的头节点。
示例 1:
输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
思路
定义一个 prev指针,指向之前的那个节点,默认值为 null。
遍历列表,直到找到该节点,对该节点进行删除操作
测试用例:
- 1 输入的头节点为 null
- 2 输入的需要删除的节点的值 不存在
- 3 删除头节点
- 4 删除尾节点
代码
class Solution {
public ListNode deleteNode(ListNode head, int val) {
if(head == null) return null;
if(head.val == val) return head.next;
ListNode prev = head;
ListNode runner = head.next;
while(runner != null && runner.val != val){
prev = runner;
runner = runner.next;
}
// 如果 runner==null,说明链表中没有指定的节点值。
// 如果不为空,说明是通过 runner.val != val 跳出循环的,进行删除节点操作
if(runner != null) prev.next = runner.next;
return head;
}
}
这里参考了 k的解法。
while循环的简洁之美
关于 while循环条件的设置: 我之前的解法是在 while循环体 中判断是否等于目标值,如果是等于的话怎样怎样。
但是参考的代码中做的很 nice。
将你想要达成的目标条件不用放在循环体中,而是放在循环头部。这样代码的精简度就上去了
两种循环方式的对比:
- 我之前的方式,删除节点再 break退出
while(runner != null){
if(runner.val == val){
prev.next = runner.next;
break;
}
prev = runner;
runner = runner.next;
}
return head;
- 简洁的方式,相当于把 判断语句和 break语句一起写到了头部
while(runner != null && runner.val != val){
prev = runner;
runner = runner.next;
}
if(runner != null) prev.next = runner.next;
return head;