LeetCode算法题合集—链表篇

发布时间:2023-02-06 21:30

链表基础算法题

链表的定义(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; }
}

1.移除链表元素

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层

2.设计链表

https://leetcode-cn.com/problems/design-linked-list/
设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:valnext。val 是当前节点的值,next 是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。

在链表类中实现这些功能:

  • get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
  • addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
  • addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
  • addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
  • deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号