继续坚持的第五天,刚刚开了个班会,疯玩了一会儿,没有害怕没有社恐,还唱了首歌哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈,现在想想应该再唱一首的,免费的KTV白去白不去呢,这样疯玩确实也给自己心中莫大的压力缓解了一点点吧,现在真的好像提个小板凳到江边去挂一会儿机,什么都不想,就静静的坐一会儿。好了进入正题,今天吾日三省吾身了吗?
吾日三省吾身
比那个男人帅吗?
比那个男人爱她吗?
比那个男人有实力吗?
思考完这些,虽然她还是在心里没有走出来,但是学习的路还是要继续走下去,那么就进入新的篇章吧。
力扣题号:203. 移除链表元素
题目描述
给你一个链表的头节点
head
和一个整数val
,请你删除链表中所有满足Node.val == val
的节点,并返回 新的头节点 。
示例
示例 1:
输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]示例 2:
输入:head = [], val = 1 输出:[]示例 3:
输入:head = [7,7,7,7], val = 7 输出:[]
链表的定义
其实链表也应该介绍一下的链表是一种通过指针串联在一起的一种线性结构,每一个节点由两部分组成
这图片网上找的,虽然不太清晰,但是还是很明显的表示出来了单链表和双链表的结构。
虽然力扣的链表这种,二叉树这种题都会给你结构,不同自己写,但是自己写出来还是可以更加清晰的了解链表,就像那个她,你和她的生活有越多的交集,你就会越了解她,她自然也会在你的身边陪你走下去。
定义代码
下面是java单链表的实现方式
public class ListNode { //节点的值 public int val; //节点储存的下一个节点 public ListNode next; //各种构造器 public ListNode() { } public ListNode(int val) { this.val = val; } public ListNode(int val, ListNode next) { this.val = val; this.next = next; } }
好了好了,既然已经初步的了解了,那么久好好的认识一下吧 。看题
思路
这是一道删除的题,其实在好好的学习过链表之后就可以清晰的发现一个秘密,这是一道链表的基础操作,很基本,就像她和你在一起的前提是她没有男朋友对吧。ok,这道题有两种写法,一种是采用虚拟头结点,也就是在头结点(第一个节点)之前再弄一个节点,它的值不重要,重要的是它存储了下一个节点的信息,就像她的过去并不重要,重要的是她的未来是不是你。通过这个虚拟头结点你可以将它模拟成新的头结点,这样后面的真正的头结点就更加好删除了,因为链表的删除一般是让删除元素的前一个节点之后删除元素的后一个节点,这样这个删除的节点就和链表没有任何的关系了,像C++这种语言可能需要自己手动回收一下这个节点,但是因为我都是使用世界上最好的语言Java(just funny),它自带垃圾回收机制我们就不用管了,所以使用虚拟头结点的话,删除头结点变得和删除普通节点一样的简单了,而且也更好理解,这里就两种都写一下吧,方便大家对比。
Java解法一:不使用虚拟头结点.
代码讲解都卸载代码里面,因为是第一次写链表的题,所以我写的很详细
class Solution {
public ListNode removeElements(ListNode head, int val) {
//执行删除操作就好了,需要判断的是每一个节点的值是否是合适的
//遇到头结点,将head往后移一位就好了
while (head != null && head.val == val){
//head.next就是head的下一位,将head的下一位赋值给head就是将head往后移
//如果理解不了,可以不把head看成一个节点,将它想成一个指针,指向头结点
//被移除的头结点在head的前面意味着被删除了
head = head.next;
}
//如果删除的不是head的话,就不要操作head了,重新定义一个指针节点代替head操作
//如果你这里还使用head操作,那么头结点一直在改变,这个链表将不成样子
//因为删除链表的逻辑,所以cur一直指向的是要删除元素的前一位
ListNode cur = head;
while (cur != null && cur.next != null){
if (cur.next.val == val){
//是要删除的元素,删除就好了
cur.next = cur.next.next;
}else {
//否则后移,继续遍历要删除节点
cur = cur.next;
}
}
return head;
}
}
害,都学了这么久算法了通过这题还是手拿把掐(*^▽^*),如果回到她的身边和这题一样简单就好了。
Java解法二:采用虚拟头结点
采用虚拟头结点使整个链表的操作可以趋于统一,免得让思路一直切换。
class Solution {
public ListNode removeElements(ListNode head, int val) {
//既然采用了虚拟头结点的方法,那么就先新建一个虚拟头节点
//值是多少并不重要
ListNode virtualHead = new ListNode(-1);
//让他指向头结点
virtualHead.next = head;
//还是需要一个指针节点代表头结点(虚拟头结点)
ListNode cur = virtualHead;
//遍历需要删除的元素
while (cur != null && cur.next != null){
if (cur.next.val == val){
cur.next = cur.next.next;
}else {
cur = cur.next;
}
}
//这里因为你不知道head有没有被删除,所以使用虚拟头结点的下一节点表示头结点
return virtualHead.next;
}
}
我测试了很多次都是1ms,确实因为加入虚拟头结点的时候会浪费一些时间但是不影响,开头总是难得,这种一劳永逸的事情开始肯定是要付出一点的,这和感情不一样,情感中你需要坚持不懈的付出,才能收获真爱。
喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔~~~~~~~~~~~~~~~!!!!!!!!!!!!!!对,开始发发疯,又完成了今天的目标。那么明天见
吾日三省吾身~~~