实例:
输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5
思路:用链表头结点或虚拟节点,先比较头结点的值是够为空或是否等于所需值,然后循环比较链表其他值
代码:
首先定义一个链表
/**
* @author shkstart
* @date 2019/6/13- 15:18
*/
public class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
//链表节点的构造函数
//使用arr为参数,创建仪的链表,当前的ListNode为链表头节点
public ListNode(int[] arr){
if(arr == null || arr.length == 0){
throw new IllegalArgumentException("arr can not be empty");
}
this.val = arr[0];
ListNode cur = this;
for (int i = 0; i < arr.length; i++) {
cur.next = new ListNode(arr[i]);
cur = cur.next;
}
}
//返回以当前节点为头结点的链表信息字符串
@Override
public String toString() {
StringBuilder res = new StringBuilder();
ListNode cur = this;
while (cur != null){
res.append(cur.val + "->");
cur = cur.next;
}
//表示达到了链表的尾部
res.append("null");
return res.toString();
}
}
实体类,这里用头结点实现
import sun.print.PeekGraphics;
/**
* @author 删除值为val的节点
* @date 2019/6/13- 15:17
*/
public class Solution {
public ListNode removeElements(ListNode head, int val) {
while(head != null && head.val == val){
/*ListNode delNode = head;
head = head.next;
delNode.next = null;*/
head = head.next;
}
if(head == null)
return head;
ListNode prev = head;
while(prev.next != null){
if(prev.next.val == val) {
/*ListNode delNode = prev.next;
prev.next = delNode.next;
delNode.next = null;*/
prev.next = prev.next.next;
}
else
prev = prev.next;
}
return head;
}
public static void main(String[] args) {
int[] nums = {1,2,6,3,4,6};
//数组转链表
ListNode head = new ListNode(nums);
System.out.println(head);
ListNode listNode = (new Solution()).removeElements(head, 6);
System.out.println(listNode);
}
}
运行
这里看出内存消耗比较大
这里还有更简单的作法
定义虚拟头节点
代码:
import javax.management.DynamicMBean;
/**
* @author shkstart
* @date 2019/6/13- 15:28
*/
public class Solution2 {
public ListNode removeElements(ListNode head, int val) {
//创建虚拟头节点
ListNode dummyHead = new ListNode(-1);
dummyHead.next = head;
ListNode prev = dummyHead;
while (prev.next != null) {
if (prev.next.val == val) {
prev.next = prev.next.next;
} else {
prev = prev.next;
}
}
return dummyHead.next;
}
}
运行main方法:
这里需要在链表中定义一个方法,将数组转链表,并重写toString方法
//链表节点的构造函数
//使用arr为参数,创建仪的链表,当前的ListNode为链表头节点
public ListNode(int[] arr){
if(arr == null || arr.length == 0){
throw new IllegalArgumentException("arr can not be empty");
}
this.val = arr[0];
ListNode cur = this;
for (int i = 0; i < arr.length; i++) {
cur.next = new ListNode(arr[i]);
cur = cur.next;
}
}
//返回以当前节点为头结点的链表信息字符串
@Override
public String toString() {
StringBuilder res = new StringBuilder();
ListNode cur = this;
while (cur != null){
res.append(cur.val + "->");
cur = cur.next;
}
//表示达到了链表的尾部
res.append("null");
return res.toString();
}
Main函数:
public static void main(String[] args) {
int[] nums = {1,2,6,3,4,6};
//数组转链表
ListNode head = new ListNode(nums);
System.out.println(head);
ListNode listNode = (new Solution()).removeElements(head, 6);
System.out.println(listNode);
}
运行:
成功!
另一只种更简洁的解法:使用递归,因为链表就是一个天然的递归
/**
* @author shkstart
* @date 2019/6/13- 16:32
*/
public class Solution3 {
public ListNode removeElements(ListNode head, int val) {
//递归实现删除 看成头结点后面跟一整个链表
if(head == null)
return null;
ListNode res = removeElements(head.next, val);
if(head.val == val){
return res;
}else {
head.next = res;
return head;
}
}
public static void main(String[] args) {
int[] nums = {0,2,6,3,4,6};
//数组转链表
ListNode head = new ListNode(nums);
System.out.println(head);
ListNode listNode = (new Solution3()).removeElements(head, 6);
System.out.println(listNode);
}
}
运行: