LeetCode.203移除链表元素(原链表操作、虚拟头结点)

news2024/12/23 9:11:37

LeetCode.203移除链表元素

  • 1.问题描述
  • 2.解题思路
  • 3.代码

1.问题描述

给你一个链表的头节点 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

2.解题思路

以链表 1 4 2 4 来举例,移除元素4。

如果使用C,C++编程语言的话,不要忘了还要从内存中删除这两个移除的节点, 清理节点内存之后如图:

当然如果使用java ,python的话就不用手动管理内存了。(就算使用C++来做leetcode,如果移除一个节点之后,没有手动在内存中删除这个节点,leetcode依然也是可以通过的,只不过,内存使用的空间大一些而已,但建议依然要养成手动清理内存的习惯。)

那么:上述例子中,删除第一个4,只要将1的next指针直接指向下下个节点就好了。但这样,如果删除的是头结点就不好办了,于是两个办法。

  1. 直接使用原来的链表来进行删除操作。

    其余节点:用上述法子便行

    头结点:移除头结点和移除其他节点的操作是不一样的,因为链表的其他节点都是通过前一个节点来移除当前节点,而头结点没有前一个节点。

    所以只要将头结点向后移动一位就可以,这样就从链表中移除了一个头结点。依然别忘将原头结点从内存中删掉。

  2. 设置一个虚拟头结点在进行删除操作。

    这里来给链表添加一个虚拟头结点为新的头结点,此时要移除这个旧头结点元素1。就和移除链表其他节点的方式统一了。最后return 头结点的时候,别忘了 return dummyNode->next;, 这才是新的头结点

3.代码

C++:直接使用原来的链表来进行删除操作

#include <iostream>
using namespace std;

struct ListNode {
	int val;
	ListNode* next;
	ListNode(int x): val(x), next(NULL) {}
};

class Solution {
	public:
		ListNode* removeElements(ListNode* head, int val) {
			// 删除头结点值等于val的节点
			//为什么不用if,因为若输入为head = [1,1,1,1,1],应为一个持续移除的过程,所以为while
			//头结点不能为空,如果为空,相当于操作空指针了
	 		while(head != NULL && head->val == val) {
				//创建了一个临时指针tmp,它指向链表的头结点head。
				//这是为了保存需要被删除的节点,以便在将指针从链表中删除时,能够释放该节点所占用的内存。
				ListNode* tmp = head;
				head = head->next;
				delete tmp;  
			}

			ListNode* cur = head;
			//cur != NULL: 确保当前节点不为空。在删除节点时,我们需要更改节点的指针来连接正确的节点,
			//所以我们要确保cur指针不为空,避免访问空指针导致程序崩溃。
			//cur->next != NULL: 确保当前节点的下一个节点不为空。在删除节点时,
			//我们需要访问当前节点的下一个节点的值来进行比较,如果下一个节点为空,
			//则没有必要进行比较和删除操作
			while(cur != NULL && cur -> next != NULL) {
				if(cur->next->val == val) {
					ListNode* tmp = cur->next;
					cur->next = cur->next->next;
					delete tmp;
				} else {
					cur = cur->next;
				}

			}
			return head;
		}
};

int main() {
    ListNode* head = new ListNode(1);
    head->next = new ListNode(2);
    head->next->next = new ListNode(6);
    head->next->next->next = new ListNode(3);
    head->next->next->next->next = new ListNode(4);
    head->next->next->next->next->next = new ListNode(5);
    head->next->next->next->next->next->next = new ListNode(6);

    int val = 6;

    Solution s;
    ListNode* res = s.removeElements(head, val);
    while (res != NULL) {
        cout << res->val << " ";
        res = res->next;
    }
    return 0;
}

C++:虚拟头结点

#include <iostream>
using namespace std;

struct ListNode {
	int val;
	ListNode* next;
	ListNode(int x): val(x), next(NULL) {}//构造函数
};

class Solution {
	public:
		ListNode* removeElements(ListNode* head, int val) {
			ListNode* dummyHead = new ListNode(0);//创建虚拟头节点
			dummyHead->next = head;//虚拟头节点指向头节点
			//临时指针从虚拟头节点开始遍历,如果直接用头结点进行遍历,那么头结点所指向的值是一直在改变的,最后无法返回了
			ListNode* cur = dummyHead;
			while(cur->next != NULL) {
				if(cur->next->val == val) {
					ListNode* tmp = cur->next;//暂存要删除的节点
					cur->next = cur->next->next;//删除节点
					delete tmp;//释放内存
				} else {
					cur = cur->next;//指向下一个节点
				}
			}
			head = dummyHead->next;//更新头节点  因为旧的head可能已经被删除了
			delete dummyHead;//释放虚拟头节点内存
			return head;//返回头节点
		}
};

int main() {
	ListNode* node1 = new ListNode(1);
	ListNode* node2 = new ListNode(2);
	ListNode* node3 = new ListNode(6);
	ListNode* node4 = new ListNode(3);
	ListNode* node5 = new ListNode(4);
	ListNode* node6 = new ListNode(5);
	ListNode* node7 = new ListNode(6);
	node1->next = node2;
	node2->next = node3;
	node3->next = node4;
	node4->next = node5;
	node5->next = node6;
	node6->next = node7;
	Solution solve;
	ListNode* newhead = solve.removeElements(node1, 6); // 删除值为6的节点
	while(newhead != NULL) {
		cout << newhead -> val << " ";
		newhead = newhead -> next;
	}
	return 0;
}

python:虚拟头结点

class ListNode:
    def __init__(self, val, next=None):
        self.val = val
        self.next = next


class Solution:
    def removeElements(self, head: ListNode, val: int) -> ListNode:
        dummyHead = ListNode()
        dummyHead.next = head
        cur = dummyHead
        while cur.next:
            if cur.next.val == val:
                cur.next = cur.next.next
            else:
                cur = cur.next
        return dummyHead.next


head = ListNode(1)
head.next = ListNode(2)
head.next.next = ListNode(6)
head.next.next.next = ListNode(3)
head.next.next.next.next = ListNode(4)
head.next.next.next.next.next = ListNode(5)
head.next.next.next.next.next.next = ListNode(6)

sol = Solution()
new_head = sol.removeElements(head, 6)

cur = new_head

while cur:
    print(cur.val)
    cur = cur.next

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1252188.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WGCLOUD 中文繁体版本 下载

wgcloud 繁体版下载 下載繁體版安裝包 - WGCLOUD

AJAX技术-04-- 跨域说明

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1 同源策略同源策略介绍规定要求 请求协议://域名:端口号 关于同源策略练习关于同源策略总结 2.JSONPJSONP原理说明关于JSONP优化 3.CORS介绍介绍不允许跨域说明跨域…

基于OGG实现Oracle实时同步MySQL

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

02_MySQL体系结构及数据文件介绍

#课程目标 了解MySQL的体系结构了解MySQL常见的日志文件及作用了解事务的控制语句&#xff0c;提交和回滚能够查看当前数据库的版本和用户了解MySQL数据库如何存放数据能在使用SQL语句创建、删除数据库 #一、MySQL的体系结构 ##1、客户端(连接者) MySQL的客户端可以是某个客户…

【键盘变成了快捷键,怎么办?】

**最便捷的操作&#xff1a;**拔掉键盘有线插头&#xff0c;将键盘驱动进行卸载&#xff0c;重新插上键盘即可 键盘驱动如何卸载: 以win10为例&#xff0c;点击开始菜单栏选择设置 选择左上角系统 选择系统中&#xff0c;点击最下方关于&#xff0c;点击右侧的设备管理器 选…

用户与组管理:如何在服务器系统中管理用户和权限

你是否想过&#xff0c;当你登录到一个服务器系统时&#xff0c;你是如何被识别和授权的&#xff1f;你是否知道&#xff0c;你可以通过创建和管理用户和组来简化和优化你的系统管理工作&#xff1f;你是否想了解一些常用的用户和组管理命令和技巧&#xff1f;如果你的答案是肯…

解决Linux Visual Studio Code显示字体有问题/Liunx下Visual Studio Code更换字体

01、具体问题 在Linux下VsCode控制台与代码区显示异常&#xff0c;如下图所示&#xff1a; 代码显示 终端显示 02、解决方案 下载字体 [rootlocalhost mhzzj]$ cd /usr/share/fonts # 进入目录 [rootlocalhost fonts]$ sudo yum install git # 下载字体 [rootlocalhost fo…

.netcore 获取appsettings

我的开发环境是abpvnext net6.0 。 因为业务需要&#xff0c;从原来老项目net4.5工程里复制了一个报表导出的业务类到net6项目里面&#xff0c;但是他的获取appsettings的代码其实不用想都知道会报错。因为原来framwork时代获取appsettings的方法常见的是 System.Configura…

基础C语言编程题

int i,j; int a[3][3]; for(i0;i<3;i){for(j0;j<3;j){scanf("%d",&a[i][j]);a[i][j]a[i][j]*2;}} 6.功能&#xff1a;把20个随机数存入一个数组&#xff0c;然后输出该数组中的最大值。 int main(){int p[20];int i,max0;for(i0;i<20;i){scanf("…

Promise的总结

Promise的总结 &#xff08;1&#xff09;什么是同步&#xff0c;异步&#xff1f; 同步表示需要前一个任务完成之后&#xff0c;才会执行下一个任务&#xff0c;简而言之&#xff0c;就是上一行代码执行返回结果后&#xff0c;才会执行下一行代码&#xff08;好理解&#xf…

Spring Security 6.1.x 系列(5)—— Servlet 认证体系结构介绍

一、前言 本章主要学习Spring Security中基于Servlet 的认证体系结构&#xff0c;为后续认证执行流程源码分析打好基础。 二、身份认证机制 Spring Security提供个多种认证方式登录系统&#xff0c;包括&#xff1a; Username and Password&#xff1a;使用用户名/密码 方式…

如何给echarts的legend设置不同的样式和位置 legend分组显示

legend分组显示 给每一个图例设置不一样的位置和样式 样式如下 demo代码 option {title: {text: Stacked Line},tooltip: {trigger: axis},// legend写为数组可以给一些给某些组分配一些不一样的样式legend: [{data: [// 使用svg画任意的图形{name:Email,icon: path://"…

【Linux】gcc和g++

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和Linux还有算法 ✈️专栏&#xff1a;Linux &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 …

Java日志技术

什么是日志 日志技术 概述 日志技术的体系、Logback日志框架的概述 Logback快速入门 Logback设置日志级别

Python教程75:Pandas中DataFrame数据的修改操作

1.DataFrame数据结构的特点包括&#xff1a; 表格型的数据结构&#xff0c;具有行和列。 每一列的标签值允许使用不同的数据类型。 每个数据值都可以被修改。 结构的行数、列数允许增加或者删除。 有两个方向的标签轴&#xff0c;分别是行标签和列标签。 可以对行和列执行算术运…

基于springboot实现高校食堂移动预约点餐系统【项目源码】计算机毕业设计

基于springboot实现高校食堂移动预约点餐系统演示 Java语言简介 Java是由SUN公司推出&#xff0c;该公司于2010年被oracle公司收购。Java本是印度尼西亚的一个叫做爪洼岛的英文名称&#xff0c;也因此得来java是一杯正冒着热气咖啡的标识。Java语言在移动互联网的大背景下具备…

springboot2.0 集成swagger3+Knife4j导出离线API 配置

springboot 版本2.3.1 一、集成swagger3 引入swagger依赖包 <!--swagger3集成--><dependency><groupId>org.springframework.plugin</groupId><artifactId>spring-plugin-core</artifactId><version>2.0.0.RELEASE</version>…

最新yolov8环境搭建、推理训练一站式超详细教学

1、获取yolov8源码 访问yolov8_github官网&#xff0c;网络不稳定时可能需要加速器。yolov8源码地址 获取方式&#xff1a;直接下载或者git工具克隆 我使用git操作进行演示&#xff0c;复制github上的地址(需提前关闭加速器)。 git clone https://github.com/ultralytics/ul…

arduino的API函数

API在这里&#xff1a;Arduino Reference - Arduino Reference 我觉得一天是不可能学的完的&#xff0c;这么多呢 我现在觉得&#xff1a;不用去学习这些API&#xff0c;以后碰到再去看好了