题目
题目难度:简单
题目分析
数组在物理的存储上也是连续的,而链表则不同,它在物理的存储上是不连续的,而是一种逻辑上的连续。
首先我们来看一下Java代码中链表中每个结点的结构:
java
public class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val; this.next = next;
}
}
可以看到,每个结点都有一个val,代表着这个结点存储的值,并且每一个结点都会通过next指向下一个结点。
如果我们想要删掉某一个结点,例如我们想要将B结点删掉,实际上就是让A直接连接C,跳过B,这边是链表的删除了。
那么此时问题又出现了,原本的结点B该怎么办呢?
对于C++等语言,我们需要手动去释放B的空间,但Java的话不需要,因为Java的垃圾回收机制已经替我们完成了这个步骤,因此只需要将A直接连接到C就可以了。
但是,这时候又出现了一个问题。
如果我们比对成功的那个值,是中间的结点,那很简单,只需要让它的上一个直接连接它的下一个。
但若这个比对成功的就是头结点该怎么办呢?头结点是没有上一个结点的,所以我们需要直接让头结点的指针指向它的下一位。
方法一
这样,我们在编写代码的时候就要进行情况的区分
情况一:比对成功的结点是头结点
情况二:比对成功的结点不是头结点
方法二
如果我们在头结点的前面增加一个虚拟的头结点,即我们自己创建一个结点,连接头结点,这样在进行比对和重新连接操作的时候,就不用区分两种情况了。
在结果返回的时候,我们只需要返回这个虚拟头结点的下一个结点,即为真正的头结点。
源代码
方法一的源代码
java
class Solution {
public ListNode removeElements(ListNode head, int val) {
while (head != null && head.val == val) {head = head.next;}
if (head == null) {return head;}
ListNode pre = head;
ListNode cur = head.next;
while (cur != null) {
if (cur.val == val) {
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
return head;
}
}
方法二的源代码
java
class Solution {
public ListNode removeElements(ListNode head, int val) {
//设置一个虚拟的头结点
ListNode virtualHead=new ListNode();
virtualHead.next=head;
ListNode k=virtualHead;
while(k.next!=null){
if(k.next.val==val){
k.next=k.next.next;
}else{
k=k.next;
}
}
return virtualHead.next;
}
}