数据结构(单链表算法题)

news2024/11/15 9:52:10
  • 1.删除链表中等于给定值 val 的所有节点。 OJ链接

typedef struct ListNode ListNode;

struct ListNode {
	int val;
	struct ListNode* next;
};

struct ListNode* removeElements(struct ListNode* head, int val) {
	
	//创建新链表
	ListNode* newhead, *newtail;
	newhead = newtail = NULL;

	//遍历原链表
	ListNode* pcur = head;

	while (pcur)
	{
		if (pcur->val != val)                            //遍历原链表,直到遍历至原链表的值与 val 的结点
		{
			if (newhead == NULL)                         //链表为空
			{
				newhead = newtail = NULL;
			}
			else                                         //链表不为空,将原链表的结点尾插到新链表中
			{
				newtail->next = pcur;
				newtail = newtail->next;
			}

		}
		pcur = pcur->next;
	}
	if (newtail)                                         //如果操作完后新的链表不为空,才能 newtail->next = NULL        ;           
	{
		newtail->next = NULL;
	}
	return newhead;

}
  • 思路:创建新链表,将原链表中值不为val的结点尾插到新链表

  • 2.反转一个单链表。 OJ链接

struct ListNode* reverseList(struct ListNode* head) {
	//处理空链表
	if (head == NULL)
	{
		return NULL;
	}

	//创建三个指针
	ListNode* n1, * n2, * n3;
	n1 = NULL; 
	n2 = head;
	n3 = n2->next;
	
	while (n2)
	{
		n2->next = n1;
		n1 = n2;
		n2 = n3;
		
		if (n3)
		{
			n3 = n3->next;
		}
	}
	return n1;
}
  • 思路:创建三个指针,在原链表上就可以修改指针的指向

原链表:       

循环一次后:

以此类推,当 n2 为 NULL 时跳出循环,此时 n1 指向的结点就是链表的新的头结点

(注意:在判断 n3 时要注意他是否已经跳出链表了,因为 n3 是移动的最快的,如果已经跳出链表就不能进行 ->next 操作) 

  • 3.给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。OJ链接

 

struct ListNode* middleNode(struct ListNode* head) {
	ListNode* slow=head, * fast=head;                 //创建两个指针,快慢指针
	while (fast && fast->next) 
	{
		slow = slow->next;                            //慢指针每次走一步,快指针每次走两步
		fast = fast->next->next;
	}
	return slow;                                      //此时慢指针 slow 指向的节点刚好就是中间的结点
}
  • 思路:快慢指针,慢指针每次走一步,快指针每次走两步

当链表长度为奇数时:

 当链表长度为偶数时:

(注意:while 中的(fast && fast->next)顺序不能更改,当 fast 已经为空时,如果改成 

(fast->next && fast),条件会先按顺序执行 fast->next ,从而报错) 

  • 慢指针每次走一步,快指针每次走两步,当快指针走到链表的结尾时,假设链表的长度为 n ,快指针走的路程是慢指针的两倍,此时慢指针走的路程就是 n/2.

  •  4.输入一个链表,输出该链表中倒数第k个结点。 OJ链接

int kthToLast(struct ListNode* head, int k) {
	ListNode* fast = head,*slow=head;
	while (k--)
	{
		fast = fast->next;
	}
	while (fast)
	{
		slow = slow->next;
		fast = fast->next;
	}

	return slow->val;

}
  • 思路:创建两个指针,1、先让 fast 向前走K步;
  •                                     2、slow 和 fast 同步前进,fast 到结尾,slow 到目标。

当 fast =NULL

  •  5.将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。OJ链接

 

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {

	//处理链表为空
	if (list1 == NULL)                           //l1为空时,返回l2
	{
		return list2;
	}
	if (list2 == NULL)                           //l2为空时,返回l1
	{
		return list1;
	}

	ListNode* newhead, * newtail;               //创建新的链表
	newhead = newtail = (ListNode*)malloc(sizeof(ListNode));            //创建一个非空链表,减少了判断链表为空和非空情况导致的代码冗余
	ListNode* l1 = list1;                       //创建两个指针分别指向两个链表的头结点
	ListNode* l2 = list2;

	//进行比较尾插
	while (l1 && l2)
	{
		if (l1->val < l2->val)
		{
			newtail->next = l1;
			newtail = newtail->next;
			l1 = l1->next;

		}
		else
		{
			newtail->next = l2;
			newtail = newtail->next;
			l2 = l2->next;
		}
	}

	if (l1)                                     //跳出循环只用两种情况:要么 l1 为空(l2 肯定不为空);要么 l2 为空(l1 肯定不为空)
	{
		newtail->next = l1;
		
	}
	if (l2)
	{
		newtail->next = l2;
	}
	ListNode* ret = newhead->next;
	free(newhead);
	newhead = NULL;
	return ret;
}
  •  思路:创建新链表,遍历原链表,谁小就尾插到新链表中

  • 6.编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前 。OJ链接

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        // write code here
        ListNode* lesshead,*lesstail;
        lesshead=lesstail=(ListNode*)malloc(sizeof(ListNode));   //大链表

        ListNode* greathead,*greattail;
        greathead=greattail=(ListNode*)malloc(sizeof(ListNode)); //小链表

        ListNode* pcur =pHead;                                //遍历链表
        while(pcur)
        {
            if(pcur->val<x)                          //当原链表结点的值小于 x,尾插到小链表 
            {
                lesstail->next=pcur;
                lesstail=lesstail->next;
                
            }
            else                                    //当原链表结点的值大于 x,尾插到大链表 
            {
                greattail->next=pcur;
                greattail=greattail->next;
            }
            pcur=pcur->next;
        }

        greattail->next=NULL;                       //将大链表的尾结点的 next 指针置为NULL

        lesstail->next=greathead->next;              // 大小链表首尾相连

        ListNode* ret= lesshead->next;

        free(lesshead);
        free(greathead);
        lesshead=greathead=NULL;

        return ret;

    }
};
  •  思路:创建大链表、小链表,将小于 x 值的结点尾插到对应的链表中,最后小链表的尾与大链表的头相连。
  • (注意:不能忘了最后将大链表的 next 指针指向= NULL)

  • 7.链表的回文结构。OJ链接 

bool chkPalindrome(ListNode* A) 
    {
        // write code here

        ListNode* mid=middleNode(A);           //找出原链表的中间结点

        ListNode*right=reverseList(mid);      //以次中间结点为头结点反转后面的链表

        ListNode*left=A;                    //从原链表和反链表比较结点的值

        while(right)
        {
            if(left->val!=right->val)
            {
                return false;
            }
            left=left->next;
            right=right->next;
           
        }

        return true;

    }
  • 思路:1、找出链表的中间结点
  •            2、将中间结点之后的链表进行反转
  •            3、从原链表和反链表比较结点的值

未完待续~~

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

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

相关文章

视频联网共享平台LntonCVS视频监控汇聚平台视频云解决方案

LntonCVS流媒体平台是一款遵循国家GB28181标准协议的先进视频监控与云服务平台。该平台设计独特&#xff0c;能够同时接入并处理多路设备的视频流&#xff0c;支持包括RTSP、RTMP、FLV、HLS、WebRTC在内的多种视频流格式的分发。其功能丰富多样&#xff0c;涵盖了视频直播监控、…

如何在Mac下修改VSCode侧边栏字体大小

在日常使用VSCode&#xff08;Visual Studio Code&#xff09;进行开发时&#xff0c;我们有时需要对IDE&#xff08;集成开发环境&#xff09;的界面进行一些个性化的调整&#xff0c;以提升我们的开发体验。 比如&#xff0c;有些用户可能会觉得VSCode的侧边栏字体大小不符…

国产麒麟、UOS在线打开pdf加盖印章

PageOffice支持两种电子印章方案&#xff0c;可实现对Word、Excel、PDF文档加盖PageOffice自带印章或ZoomSeal电子印章&#xff08;全方位保护、防篡改、防伪造&#xff09;。Word和Excel的盖章功能请参考&#xff1a;Word和Excel加盖印章和签字功能 &#xff08;目前只支持win…

FastAPI 学习之路(五十九)封装统一的json返回处理工具

在本篇文章之前的接口&#xff0c;我们每个接口异常返回的数据格式都不一样&#xff0c;处理起来也没有那么方便&#xff0c;因此我们可以封装一个统一的json。 from fastapi import status from fastapi.responses import JSONResponse, Response from typing import Unionde…

[C/C++入门][进制原理]27、计算机种的进制

各种信息进入计算机&#xff0c;都要转换成“0”和“1”的二进制形式。 计算机 采用二进制的原因是&#xff1a; 物理上容易实现&#xff0c;可靠性高。&#xff08;电子元件的通电和不通电就可以表示1和0&#xff0c;所以非常方便&#xff09;运算简单&#xff0c;通用性强。…

【Git远程操作】理解分布式管理 | 创建远程仓库

目录 1.理解分布式管理 多人协作开发 2.创建远程仓库 2.1仓库名&路径 2.2初始化仓库&设置模板 1.理解分布式管理 目前我们学习的所有内容都是在本地来完成的。&#xff08;add /commit /版本撤销回退/分支管理&#xff09; Git是一个分布式 的版本控制系统。 分支…

最新开源的解析效果非常好的PDF解析工具MinerU (pdf2md pdf2json)

毫不夸张的说 PDF解析工具MinerU是照进RAG黑暗中的一道光——这是我对它的评价。我测过太多了文档解析工具&#xff01; 最近在做文档解析的工作。看了很多的开源的文档解析的工具&#xff0c;版面分析的工具&#xff0c;其中包括paddelpaddel这样30kstar的明星工具。但是效果都…

Android SurfaceView 组件介绍,挖洞原理详解

文章目录 组件介绍基本概念关键特性使用场景 SurfaceHolder介绍主要功能使用示例 SurfaceView 挖洞原理工作机制 使用SurfaceView展示图片示例创建一个自定义的 SurfaceView类在 Activity 中使用 ImageSurfaceView注意事项效果展示 组件介绍 在 Android 开发中&#xff0c;Sur…

【20】读感 - 架构整洁之道(二)

概述 继上一篇文章讲了前两章的读感&#xff0c;已经归纳总结的重点&#xff0c;这章会继续跟进的看一下&#xff0c;深挖架构整洁之道。 编程范式 编程范式从早期到至今&#xff0c;提过哪些编程范式&#xff0c;结构化编程&#xff0c;面向对象编程&#xff0c;函数式编程…

前端学习(二)之HTML

一、HTML文件结构 <!DOCTYPE html> <!-- 告诉浏览器&#xff0c;这是一个HTML文件 --><html lang"en"> <!-- 根元素&#xff08;起始点&#xff0c;最外层容器&#xff09; --><head> <!-- 文档的头部&#xff08;元信息&#xff…

spring ioc的原理

1、控制反转(IOC):对象的创建控制权由程序自身转移到外部&#xff08;容器&#xff09; 2、依赖注入(DI):所谓依赖注入&#xff0c;就是由IOC容器在运行期间&#xff0c;动态地将某种依赖关系注入到对象之中。 Spring 中的 IoC 的实现原理就是工厂模式加反射机制。 参考资料…

C++:类和对象 III(初始化列表、explicit、友元、匿名对象)

目录 初始化列表 初始化列表的特点 类型转换、explicit 隐式类型转换 explicit关键字 static成员 静态成员变量 静态成员函数 友元 友元函数 友元类 内部类 匿名对象 编译器优化 初始化列表 初始化列表就是类成员初始化的地方 函数有它声明和定义的地方&#x…

【人工智能】在未来智慧城市的建设及应用分析

作者主页: 知孤云出岫 目录 作者主页:案例分析&#xff1a;人工智能在未来智慧城市的建设及其影响和应用引言一、人工智能在智慧城市中的关键应用领域 案例分析&#xff1a;人工智能在未来智慧城市的建设及其影响和应用 引言 智慧城市是利用信息和通信技术&#xff08;ICT&am…

【开源 Mac 工具推荐之 2】洛雪音乐(lx-music-desktop):免费良心的音乐平台

旧版文章&#xff1a;【macOS免费软件推荐】第6期&#xff1a;洛雪音乐 Note&#xff1a;本文在旧版文章的基础上&#xff0c;新更新展示了一些洛雪音乐的新功能&#xff0c;并且描述更为详细。 简介 洛雪音乐&#xff08;GitHub 名&#xff1a;lx-music-desktop &#xff09;…

政安晨【零基础玩转各类开源AI项目】基于Ubuntu系统部署Hallo :针对肖像图像动画的分层音频驱动视觉合成

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: 零基础玩转各类开源AI项目 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 本文目标&#xff1a;在Ubuntu系统上部署Hallo&#x…

Linux——Shell脚本和Nginx反向代理服务器

1. Linux中的shell脚本【了解】 1.1 什么是shell Shell是一个用C语言编写的程序&#xff0c;它是用户使用Linux的桥梁 Shell 既是一种命令语言&#xff0c;有是一种程序设计语言 Shell是指一种应用程序&#xff0c;这个应用程序提供了一个界面&#xff0c;用户通过这个界面访问…

香橙派AIpro-携手华为-为AI赋能

文章目录 香橙派AIpro-携手华为-为AI赋能开箱和功能介绍开箱功能介绍 环境搭建镜像烧录进入系统 测试项目YOLOv5部署YOLOv5识别单张图片实时识别视频使用Ascend测试yolov5 产品评价 香橙派AIpro-携手华为-为AI赋能 今天新入手了一款香橙派AIPro&#xff0c;让我们一起跟着文章…

ELK日志分析系统部署文档

一、ELK说明 ELK是Elasticsearch&#xff08;ES&#xff09; Logstash Kibana 这三个开源工具组成&#xff0c;官方网站: The Elastic Search AI Platform — Drive real-time insights | Elastic 简单的ELK架构 ES: 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它…

适用于618/7xx芯片平台 AT开发 远程FOTA升级指南教程

简介 AT版本的远程升级主要是对AT固件版本进行升级&#xff0c;实际方式为通过合宙官方IOT平台升级或者使用自己搭建的服务器进行升级服务。 该文档教程流程适用于 618/716S/718P 芯片平台的Cat.1模块 合宙IOT平台配置 升级日志 —— 如何查看 升级日志 —— 响应码列表 响应…

算法之判断对称二叉树

94. 二叉树的中序遍历101. 对称二叉树 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;fa…