leetcode快速入门

文章提供了几种删除链表中具有特定值的节点的方法,包括直接删除、添加虚节点以及使用辅助节点。同时,文章还介绍了如何设计和实现一个简单的链表数据结构MyLinkedList,包括其主要方法如添加、删除和获取节点值等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第四天

链表篇

/**
* 给你一个链表的头节点 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
* 输出:[]
*
*
* 提示:
*
* 列表中的节点数目在范围 [0, 104] 内
* 1 <= Node.val <= 50
* 0 <= val <= 50
*/

 public static class ListNode {
         int val;
         ListNode next;
         ListNode() {}
         ListNode(int val) { this.val = val; }
         ListNode(int val, ListNode next) { this.val = val; this.next = next; }
    }

    /**
     * 时间复杂度 O(n)
     * 空间复杂度 O(1)
     * @param head
     * @param val
     * @return
     */
    public static ListNode removeElements(ListNode head, int val) {
        ListNode listNode = head;

        while (listNode.next.next!=null){
            while (listNode.next!=null&&listNode.next.val==val){
                listNode.next = listNode.next.next;
            }
            listNode = listNode.next;
            if(listNode==null||listNode.next==null){
                break;
            }
        }
        return head.next;
    }

    public static ListNode removeElements3(ListNode head, int val) {
        while(head!=null && head.val==val){
            head = head.next;
        }
        ListNode curr = head;
        while(curr!=null){
            while(curr.next!=null && curr.next.val == val){
                curr.next = curr.next.next;
            }
            curr = curr.next;
        }
        return head;
    }

    /**
     * 添加虚节点方式:添加一个指向当前循环链表节点的父节点
     * 时间复杂度 O(n)
     * 空间复杂度 O(1)
     * @param head
     * @param val
     * @return
     */
    public static ListNode removeElements2(ListNode head, int val) {
        if (head == null) {
            return head;
        }
        // 因为删除可能涉及到头节点,所以设置dummy节点,统一操作
        ListNode dummy = new ListNode(-1, head);
        ListNode pre = dummy;
        ListNode cur = head;
        while (cur != null) {
            if (cur.val == val) {
                pre.next = cur.next;
            } else {
                pre = cur;
            }
            cur = cur.next;
        }
        return dummy.next;
    }

/**
* 你可以选择使用单链表或者双链表,设计并实现自己的链表。
*
* 单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。
*
* 如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。
*
* 实现 MyLinkedList 类:
*
* MyLinkedList() 初始化 MyLinkedList 对象。
* int get(int index) 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。
* void addAtHead(int val) 将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。
* void addAtTail(int val) 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。
* void addAtIndex(int index, int val) 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。
* void deleteAtIndex(int index) 如果下标有效,则删除链表中下标为 index 的节点。
*
*
* 示例:
*
* 输入
* [“MyLinkedList”, “addAtHead”, “addAtTail”, “addAtIndex”, “get”, “deleteAtIndex”, “get”]
* [[], [1], [3], [1, 2], [1], [1], [1]]
* 输出
* [null, null, null, null, 2, null, 3]
*
* 解释
* MyLinkedList myLinkedList = new MyLinkedList();
* myLinkedList.addAtHead(1);
* myLinkedList.addAtTail(3);
* myLinkedList.addAtIndex(1, 2); // 链表变为 1->2->3
* myLinkedList.get(1); // 返回 2
* myLinkedList.deleteAtIndex(1); // 现在,链表变为 1->3
* myLinkedList.get(1); // 返回 3
*
*
* 提示:
*
* 0 <= index, val <= 1000
* 请不要使用内置的 LinkedList 库。
* 调用 get、addAtHead、addAtTail、addAtIndex 和 deleteAtIndex 的次数不超过 2000 。
*
* 来源:力扣(LeetCode)
* 链接:力扣原题链接
*/

 static class ListNode2 {
        int val;
        ListNode2 next;
        ListNode2(){}
        ListNode2(int val) {
            this.val=val;
        }
    }

    static class  MyLinkedList {
        private final ListNode2 first;
        private ListNode2 last;
        public int size;

        public MyLinkedList() {
            size = 0;
            first = new ListNode2(0);
            last = first;
        }

        public int get(int index) {
            if(size<=index||index<0){
                return -1;
            } else {
                ListNode2 listNode = this.first;
                while (index>=0){
                    if(index==0){
                        return listNode.val;
                    } else {
                        listNode = listNode.next;
                        index--;
                    }
                }
            }
            return -1;
        }

        public void addAtHead(int val) {
            ListNode2 newHeadNode = new ListNode2(val);
            newHeadNode.next = this.first.next;
            this.first.next = newHeadNode;
            if(newHeadNode.next == null){
                this.last = newHeadNode;
            }
            this.size++;
        }

        public void addAtTail(int val) {
            ListNode2 newTailNode = new ListNode2(val);
            this.last.next = newTailNode;
            this.last = newTailNode;
            size++;
        }

        public void addAtIndex(int index, int val) {
            if (index <= 0 || index >= size) {
                if (index == size) {
                    addAtTail(val);
                } else if (index == 0) {
                    addAtHead(val);
                }
                return;
            }
            int i = 0;
            for (ListNode2 x = first; x.next != null; x = x.next, ++i) {
                if (i == index) {
                    ListNode2 node = new ListNode2(val);
                    node.next = x.next;
                    x.next = node;
                    size++;
                }
            }
        }

        public void deleteAtIndex(int index) {
            if (index < 0 || index >= size) {
                return;
            }
            int i = 0;
            for (ListNode2 x = first; x.next != null; x = x.next, ++i) {
                if (i == index) {
                    x.next = null == x.next.next ? null : x.next.next;
                    size--;
                    if (size == 0) {
                        last = first;
                    } else if (index == size) {
                        last = x;
                    }
                    return;
                }
            }
        }
    }

欢迎各位大佬在评论区指点讨论
参考链接:代码随想路

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值