剑指 Offer 18. 删除链表的节点(简单)
题目描述:
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。返回删除后的链表的头节点。
注意:此题对比原题有改动
之所以写这一题,是因为正在学习链表,学习了带头节点的单链表。
看见了这一题,我想当然的上去就是一顿啪啪的写了用头节点的方式(把参数看成带头节点了)。结果不出所料,报错了。
代码如下:好家伙,连第一个示例都没过。干的漂亮!
public ListNode deleteNode(ListNode head, int val) {
//判断单链表是否为空
if(head.next == null){
return null;
}
//定义辅助变量,帮助循环查找需要删除的节点
ListNode temp = head;
//标注是否找到,true:找到,fasle:未找到
boolean isFlag = false;
while(true){
//判断是否到链表末尾
if(temp.next == null){
return null;
}
//需要找到需要删除的节点的前一个节点,因为使前一节点的next指向下一节点的next的next
if(temp.next.val == val){
isFlag = true;
break;
}
//循环,遍历
temp = temp.next;
}
//判断是否找到
if(isFlag){
temp.next = temp.next.next;
return temp;
}else{
return head;
}
}
后来老夫夜观天象,掐指一算,啪啪啪修改代码:
public ListNode deleteNode(ListNode head, int val) {
ListNode tempNode = new ListNode(0);
tempNode.next = head;
//判断单链表是否为空
if(tempNode.next == null){
return null;
}
//定义辅助变量,帮助循环查找需要删除的节点
ListNode temp = tempNode;
//标注是否找到,true:找到,fasle:未找到
boolean isFlag = false;
while(true){
//判断是否到链表末尾
if(temp.next == null){
return null;
}
//需要找到需要删除的节点的前一个节点,因为使前一节点的next指向下一节点的next的next
if(temp.next.val == val){
isFlag = true;
break;
}
//循环,遍历
temp = temp.next;
}
//判断是否找到
if(isFlag){
temp.next = temp.next.next;
return head;
}else{
return head;
}
}
不出所料,报错了!!!!在第35个报错了。
没想到,我大意了,没有闪。居然要删除头节点。于是老夫在掐指一算,在夜观天象,啪啪啪修改代码:
public ListNode deleteNode(ListNode head, int val) {
/*题解:链表需要删除节点时,需要找到删除节点的前一个节点。(双指针)
1、当val 在第一个时:
直接返回下一个节点;
2、当val不在第一个时:
定义两个变量,一个为第一个,另一个为第一个的后一个
*/
//1、判断val是否在第一个节点l
if(head.val == val){
return head.next;
}
//定义两个变量,保存第一个节点 和 第一个节点的后一个节点
ListNode front = head, rear = head.next;
//反向思路,减少代码:以 Xxx.val != val为条件,不满足时,即为找到
while(rear != null && rear.val != val){
//前节点
front = rear;
//后节点
rear = rear.next;
}
//跳出循环,代表找到了或者rear = null
if(rear != null){//剔除rear = null
//将前节点的next指向后节点的next
front.next = rear.next;
}
return head;
}
不出所料,成功了!!!!,居然没报错。
问题 记录:
- 想的太简单,不细心。
- 写完代码不检查
- 思考太片面化,争取多元化