首页 > 其他分享 >203_移除链表元素

203_移除链表元素

时间:2024-09-30 09:25:11浏览次数:7  
标签:203 ListNode val head next 链表 移除 prev 节点

203_移除链表元素

【问题描述】

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点

示例一:
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]

示例二:
输入:head = [], val = 1
输出:[]

示例三:
输入:head = [7,7,7,7], val = 7
输出:[]

提示:

  • 列表中的节点数目在范围 [0, 104]
  • 1 <= Node.val <= 50
  • 0 <= val <= 50

【算法设计思想】

  1. 首先是应对重复出现的情况,例如1、1、1、1、这样的链表,我们可以使用一个while循环来逐个删除。
  2. 然后是检查head,即当前链表是否为空,如果是空,那么我们直接返回head就好了。
  3. 最后是一般情况,使用while循环来处理一般的情况,在这里需要注意prev->next->val的值不是val时才移动指针,否则会出现跳过重复元素的情况。

【算法描述】

C++:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        // 移除所有位于链表头部且值为val的节点
        while (head != nullptr && head->val == val) {
            ListNode* toDelete = head; // 保存当前头节点
            head = head->next; // 更新头节点为下一个节点
            delete toDelete; // 释放被删除节点的内存
        }

        // 如果链表为空,直接返回
        if (head == nullptr)
            return head;

        // 初始化 prev 指针,从头节点开始
        ListNode* prev = head;
        
        // 遍历链表,移除值为val的节点
        while (prev->next != nullptr) {
            if (prev->next->val == val) {
                ListNode* temp = prev->next; // 保存需要删除的节点
                prev->next = temp->next; // 跳过需要删除的节点
                delete temp; // 释放被删除节点的内存
            } else {
                prev = prev->next; // 只有当 prev->next 的值不是 val 时才移动 prev 指针
            }
        }

        return head; // 返回处理后的链表头节点
    }
};

Java:

/**
 * Definition for singly-linked list.
 * 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; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        // 移除所有位于链表头部且值为val的节点
        while (head != null && head.val == val) {
            ListNode toDelete = head; // 保存当前头节点
            head = head.next; // 更新头节点为下一个节点
            toDelete = null; // 释放被删除节点的引用,让垃圾回收器回收
        }
        
        // 如果链表为空,直接返回
        if (head == null) {
            return head;
        }

        // 初始化 prev 指针,从头节点开始
        ListNode prev = head;
        
        // 遍历链表,移除值为val的节点
        while (prev.next != null) {
            if (prev.next.val == val) {
                ListNode temp = prev.next; // 保存需要删除的节点
                prev.next = temp.next; // 更新 prev.next 指向下一个节点
                temp = null; // 释放被删除节点的引用,让垃圾回收器回收
            } else {
                prev = prev.next; // 只有当 prev.next 的值不是 val 时才移动 prev 指针
            }
        }
        
        return head; // 返回处理后的链表头节点
    }
}

Python:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next

class Solution:
    def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
        # 移除所有位于链表头部且值为val的节点
        while head is not None and head.val == val:
            toDelete = head  # 保存当前头节点
            head = head.next  # 更新头节点为下一个节点
            del toDelete  # 释放被删除节点的内存
        
        # 如果链表为空,直接返回
        if head is None:
            return head
        
        # 初始化 prev 指针,从头节点开始
        prev = head
        
        # 遍历链表,移除值为val的节点
        while prev.next is not None:
            if prev.next.val == val:
                temp = prev.next  # 保存需要删除的节点
                prev.next = temp.next  # 更新 prev.next 指向下一个节点
                del temp  # 释放被删除节点的内存
            else:
                prev = prev.next  # 只有当 prev.next 的值不是 val 时才移动 prev 指针
        
        return head  # 返回处理后的链表头节点
      

C:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

struct ListNode* removeElements(struct ListNode* head, int val) {
    // 移除所有位于链表头部且值为val的节点
    while (head != NULL && head->val == val) {
        struct ListNode* temp = head; // 保存当前头节点
        head = head->next; // 更新头节点为下一个节点
        free(temp); // 释放被删除节点的内存
    }

    // 如果链表为空,直接返回
    if (head == NULL) {
        return head;
    }

    // 初始化 prev 指针,从头节点开始
    struct ListNode* prev = head;

    // 遍历链表,移除值为val的节点
    while (prev->next != NULL) {
        if (prev->next->val == val) {
            struct ListNode* temp = prev->next; // 保存需要删除的节点
            prev->next = temp->next; // 更新 prev.next 指向下一个节点
            free(temp); // 释放被删除节点的内存
        } else {
            prev = prev->next; // 只有当 prev.next 的值不是 val 时才移动 prev 指针
        }
    }

    return head; // 返回处理后的链表头节点
}

标签:203,ListNode,val,head,next,链表,移除,prev,节点
From: https://www.cnblogs.com/zeta186012/p/18441165

相关文章

  • 视野修炼-技术周刊第103期 | 优雅的移除事件
    欢迎来到第103期的【视野修炼-技术周刊】,下面是本期的精选内容简介......
  • c语言实现:链表创建、插入、删除、翻转
    #include<stdio.h>#include<stdlib.h>//链表创建typedefstructNode{intdata;structNode*next;}Node;//创建一个节点Node*createNode(intdata){Node*newNode=(Node*)malloc(sizeof(Node));newNode->data=data;newNode......
  • 移除元素
    第一个想法就是利用两个for循环暴力解决#include<iostream>#include<vector>usingnamespacestd;classSolution{public:intremoveElement(vector<int>&nums,intval){intsize=nums.size();intwriteIndex=......
  • 代码随想录算法训练营第四天|24. 两两交换链表中的节点,19.删除链表的倒数第N个节点,面
    24.两两交换链表中的节点文章链接:https://programmercarl.com/0024.两两交换链表中的节点.html#思路视频讲解:https://www.bilibili.com/video/BV1YT411g7br代码链接:https://leetcode.cn/problems/swap-nodes-in-pairs/此题注意点:注意由于交换节点,head已经变换了位置,故最终......
  • 21_合并两个有序链表
    21_合并两个有序链表【问题描述】将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。示例一:输入:l1=[1,2,4],l2=[1,3,4]输出:[1,1,2,3,4,4]示例二:输入:l1=[],l2=[]输出:[]示例三:输入:l1=[],l2=[0]输出:[0]......
  • 链表高频题
    链表高频题160.相交链表#include<vector>#include<iostream>#include<algorithm>structListNode{intval;ListNode*next;ListNode(intx):val(x),next(NULL){}};classSolution{public:ListNode*getIntersectionNode(Li......
  • 代码随想录算法训练营Day03-链表 | LC203移除链表元素、LC707设计链表、LC206反转链表
    目录前言LeetCode203.移除链表元素思路完整代码LeetCode707.设计链表思路完整代码LeetCode206.反转链表思路完整代码今日总结前言拖延症犯了,哈哈,拖了一天LeetCode203.移除链表元素给你一个链表的头节点head和一个整数val,请你删除链表中所有满足Node.val......
  • 代码随想录算法训练营第三天|203.移除链表元素,707.设计链表,206.反转链表
    203.移除链表元素文章链接:https://programmercarl.com/0203.移除链表元素.html#算法公开课视频讲解:https://www.bilibili.com/video/BV18B4y1s7R9题目出处:https://leetcode.cn/problems/remove-linked-list-elements/卡哥在这里讲解了为什么要使用虚拟头节点,以及使用和不使......
  • 面试题 02.07. 链表相交
    明天回家喽,最近在学习的瓶颈期,感觉学的东西好难,有厌学的心理,但是我相信过了这段煎熬的时期,就好了。classSolution{public:ListNode*getIntersectionNode(ListNode*headA,ListNode*headB){intna=0,nb=0;ListNode*tempA=headA;L......
  • 链表分割 1.2版本
    现有一链表的头指针ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。思路:大致可以分为两个区域来存储数据:区域一存储小于36的节点,区域二存储大于36的节点.可以将这两个区域视为两个链表......