发布时间:2023-02-06 21:30
//单链表的定义
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; }
}
https://leetcode-cn.com/problems/remove-linked-list-elements/
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
示例 1:
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]
示例 2:
输入:head = [7,7,7,7], val = 7
输出:[]
方法一:直接法—迭代
删除头结点时另做考虑
class Solution {
public ListNode removeElements(ListNode head, int val) {
while(head!=null && head.val==val){
head=head.next; //若满足条件,则移动头节点的位置
}
if(head==null) return head;
ListNode first = head; //保存头节点的位置
while(head.next!=null){
if(head.next.val==val){
head.next=head.next.next;
}else{
head=head.next;
}
}
return first;
}
}
//时间复杂度: O(n)
//空间复杂度: O(1)
方法二:虚拟头节点(常用)
设置一个虚拟头结点,不需要另外考虑头节点,这样原链表的所有节点就都可以按照统一的方式进行移除了
class Solution {
public ListNode removeElements(ListNode head, int val) {
//虚拟结点,指向下一个结点是head头节点
ListNode dummy = new ListNode(-1,head);
ListNode prev=dummy; //借用其他结点进行删除,保证dummy.next指向头节点
while(prev.next!=null){
if(prev.next.val==val){
prev.next=prev.next.next;
}else{
prev=prev.next;
}
}
return dummy.next;
}
}
//时间复杂度: O(n)
//空间复杂度: O(1)
方法三:递归
递归的终止条件是head
为空,此时直接返回head
。
当head
不为空时,递归地进行删除操作,然后判断head
的节点值是否等于val
并决定是否要删除head
。
class Solution {
public ListNode removeElements(ListNode head, int val) {
if (head == null) {
return head; //退出递归
}
head.next = removeElements(head.next, val); //下一个结点交给递归处理
return head.val == val ? head.next : head; //保证当前节点满足条件
}
}
//时间复杂度: O(n)
//空间复杂度: O(n) 其中n是链表的长度。空间复杂度主要取决于递归调用栈,最多不会超过n层
https://leetcode-cn.com/problems/design-linked-list/
设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val
和 next
。val 是当前节点的值,next 是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev
以指示链表中的上一个节点。假设链表中的所有节点都是 0-index
的。
在链表类中实现这些功能: