【数据结构与算法】之8道顺序表与链表典型编程题心决!

news2024/11/25 14:49:39

                                                                                个人主页:秋风起,再归来~

                                                                                            数据结构与算法                             

                                                                       个人格言:悟已往之不谏,知来者犹可追

                                                                                        克心守己,律己则安!

目录

1、顺序表

1.1 合并两个有序数组

1.2 原地移除数组中所有的元素val

2、链表

2.1 移除链表元素

2.2 反转链表

2.3 合并两个有序链表

2.4 链表的中间节点

2.5 环形链表的约瑟夫问题

2.6 分割链表

3、完结散花


1、顺序表

1.1 合并两个有序数组

题目描述:

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。

请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

示例 1:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。

示例 2:

输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]
解释:需要合并 [1] 和 [] 。
合并结果是 [1] 。

示例 3:

输入:nums1 = [0], m = 0, nums2 = [1], n = 1
输出:[1]
解释:需要合并的数组是 [] 和 [1] 。
合并结果是 [1] 。
注意,因为 m = 0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。

提示:

  • nums1.length == m + n
  • nums2.length == n
  • 0 <= m, n <= 200
  • 1 <= m + n <= 200
  • -109 <= nums1[i], nums2[j] <= 109

OJ链接:合并两个有序数组

 解题代码:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
    int tail=nums1Size-1;
    int p1=m-1;
    int p2=n-1;
    while(p1>=0&&p2>=0)
    {
        if(nums1[p1]>nums2[p2])
        {
            nums1[tail--]=nums1[p1--];
        }else{
            nums1[tail--]=nums2[p2--];
        }
    }
    if(p1<0)
    {
        while(p2>=0)
        {
             nums1[tail--]=nums2[p2--];
        }
    }
}

1.2 原地移除数组中所有的元素val

题目描述:

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝
int len = removeElement(nums, val);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

示例 1:

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。

示例 2:

输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,3,0,4]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0 1,3,0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。

提示:

  • 0 <= nums.length <= 100
  • 0 <= nums[i] <= 50
  • 0 <= val <= 100

OJ链接移除元素

 解题代码:

int removeElement(int* nums, int numsSize, int val) {
    if(numsSize<=0||nums==NULL)
    return 0;
    int cur=0;//用cur去遍历原数组
    int newNums=0;
    while(numsSize--)
    {
        if(nums[cur]==val)
        {
            cur++;
        }else{
            nums[newNums++]=nums[cur++];
        }
    }
    return newNums;
}

2、链表

2.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

OJ链接:移除链表元素

解题代码: 

typedef struct ListNode ListNode;
struct ListNode* removeElements(struct ListNode* head, int val) {
    if(head==NULL)
    return NULL;
    ListNode* newHead=(ListNode*)malloc(sizeof(ListNode));//创建一个带哨兵卫的头结点
    ListNode* newTail=newHead;
    ListNode* cur=head;
    while(cur)
    {
        if(cur->val==val)
        {
            cur=cur->next;
        }else{
            newTail->next=cur;
            newTail=newTail->next;
            cur=cur->next;
        }
    }
    newTail->next=NULL;
    return newHead->next;
}

2.2 反转链表

题目描述:

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:

输入:head = [1,2]
输出:[2,1]

示例 3:

输入:head = []
输出:[]

提示:

  • 链表中节点的数目范围是 [0, 5000]
  • -5000 <= Node.val <= 5000

题目链接:反转单链表

解题代码:

typedef struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head) {
    if(head==NULL)
    return NULL;
    ListNode* n1,*n2,*n3;
    n1=NULL;
    n2=head;
    n3=head->next;
    while(n2)
    {
        n2->next=n1;
        n1=n2;
        n2=n3;
        if(n3)
        {
            n3=n3->next;
        }
    }
    return n1;
}

2.3 合并两个有序链表

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

示例 1:

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例 2:

输入:l1 = [], l2 = []
输出:[]

示例 3:

输入:l1 = [], l2 = [0]
输出:[0]

提示:

  • 两个链表的节点数目范围是 [0, 50]
  • -100 <= Node.val <= 100
  • l1 和 l2 均按 非递减顺序 排列

OJ链接:合并两个有序链表

typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
    
    ListNode* newHead,*newTail;
    newTail=newHead=(ListNode*)malloc(sizeof(ListNode));
    ListNode* l1=list1;
    ListNode* l2=list2;
    while(l1&&l2)
    {
        if((l1->val)<(l2->val))
        {
            newTail->next=l1;
            l1=l1->next;
        }else{
            newTail->next=l2;
            l2=l2->next;
        }
        newTail=newTail->next;
    }
    if(l1)
    {
        newTail->next=l1;
    }else{
        newTail->next=l2;
    }
    return newHead->next;
}

2.4 链表的中间节点

给你单链表的头结点 head ,请你找出并返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。

示例 1:

输入:head = [1,2,3,4,5]
输出:[3,4,5]
解释:链表只有一个中间结点,值为 3 。

示例 2:

输入:head = [1,2,3,4,5,6]
输出:[4,5,6]
解释:该链表有两个中间结点,值分别为 3 和 4 ,返回第二个结点。

提示:

  • 链表的结点数范围是 [1, 100]
  • 1 <= Node.val <= 100

OJ链接链表的中间节点

typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head) {
    if(head==NULL)
    return NULL;
    ListNode* fast,*slow;
    fast=slow=head;
    while(fast&&fast->next)
    {
        fast=fast->next->next;
        slow=slow->next;
    }
    return slow;
}

2.5 环形链表的约瑟夫问题

编号为 1 到 n 的 n 个人围成一圈。从编号为 1 的人开始报数,报到 m 的人离开。

下一个人继续从 1 开始报数。

n-1 轮结束以后,只剩下一个人,问最后留下的这个人编号是多少?

数据范围: 1≤n,m≤10000

进阶:空间复杂度O(1),时间复杂度 O(n)

   OJ链接:环形链表的约瑟夫问题

typedef struct ListNode ListNode;
ListNode* byNode(int x)
{
    ListNode* node=(ListNode*)malloc(sizeof(ListNode));
    if(node==NULL)
    {
        exit(1);
    }
    node->val=x;
    return node;
}
ListNode* creatCircle(int x)
{
    ListNode* head=(ListNode*)malloc(sizeof(ListNode));//创建头结点
    if(head==NULL)
    {
        exit(1);
    }
    ListNode* tail=head;
    for(int i=1;i<=x;i++)
    {
        tail->next=byNode(i);
        tail=tail->next;
    }
    tail->next=head->next;
    return tail;
}

int ysf(int n, int m ) {
    // write code here
    //创建循环链表并返回尾节点
    ListNode* prev=creatCircle(n);
    ListNode* cur=prev->next;
    int count=1;//报数
    while(cur!=cur->next)
    {
        if(count==m)
        {
            prev->next=cur->next;
            free(cur);
            cur=prev->next;
            count=1;//重置为1
        }else {
            prev=cur;
            cur=cur->next;
            count++;
        }
    }
    return cur->val;
}

2.6 分割链表

给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。

你不需要 保留 每个分区中各节点的初始相对位置。

示例 1:

输入:head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]

示例 2:

输入:head = [2,1], x = 2
输出:[1,2]

提示:

  • 链表中节点的数目在范围 [0, 200] 内
  • -100 <= Node.val <= 100
  • -200 <= x <= 200

OJ链接:分割链表

typedef struct ListNode ListNode;
struct ListNode* partition(struct ListNode* head, int x){
    if(head==NULL)
    {
        return NULL;
    }
    //创建两个头结点
    ListNode* lessHead=(ListNode*)malloc(sizeof(ListNode));
    if(lessHead==NULL)
    {
        exit(1);
    }
    ListNode* greaterHead=(ListNode*)malloc(sizeof(ListNode));
    if(greaterHead==NULL)
    {
        exit(1);
    }
    ListNode* lessTail=lessHead;
    ListNode* greaterTail=greaterHead;
    lessHead->next=greaterHead->next=NULL;
    ListNode* cur=head;
    while(cur)
    {
        if(cur->val<x)
        {
            lessTail->next=cur;
            lessTail=lessTail->next;
        }else{
            greaterTail->next=cur;
            greaterTail=greaterTail->next;
        }
        cur=cur->next;
    }
    lessTail->next=greaterHead->next;
    greaterTail->next=NULL;
    return lessHead->next;
}

3、完结散花

好了,这期的分享到这里就结束了~

如果这篇博客对你有帮助的话,可以用你们的小手指点一个免费的赞并收藏起来哟~

如果期待博主下期内容的话,可以点点关注,避免找不到我了呢~

我们下期不见不散~~

​​​​

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

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

相关文章

Python+selenium搭建Web自动化测试框架

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 在程序员的世界中&#xff0c;一切重复性的工作&#xff0c;都应该通过程序自动执行。「自动化测…

Uniapp+基于百度智能云完成AI视觉功能(附前端思路)

本博客使用uniapp百度智能云图像大模型中的AI视觉API&#xff08;本文以物体检测为例&#xff09;完成了一个简单的图像识别页面&#xff0c;调用百度智能云API可以实现快速训练模型并且部署的效果。 uniapp百度智能云AI视觉页面实现 先上效果图实现过程百度智能云Easy DL训练图…

Proxmox VE qm 方式一键创建Windows虚拟机

前言 实现qm 方式一键创建Windows虚拟机&#xff0c;提高效率。 qm 一键创建Windows虚拟机 以下实现在线下载镜像&#xff0c;创建虚拟机&#xff0c;安装系统需要自己手动安装哦&#xff0c;如果想实现全自动安装系统&#xff0c;建议部署自己的内网pxe server 系统参考各参…

蓝桥杯——松散子序列

题目 分析 很明显的动态规划问题&#xff0c;每次我们都取当前位置的最大值就可&#xff0c;从头开始&#xff0c;dp[i]max(dp[i-2],dp[i-3])num[i-3]. 代码 ninput() num[] for i in n:num.append(ord(i)-96) dp[0]*(len(num)3) for i in range(3,len(num)3):dp[i]max(dp[i…

基于特征的多模态生物信号信息检索与自相似矩阵:专注于自动分割

论文地址&#xff1a;Biosensors | Free Full-Text | Feature-Based Information Retrieval of Multimodal Biosignals with a Self-Similarity Matrix: Focus on Automatic Segmentation (mdpi.com) 论文源码&#xff1a;无 期刊&#xff1a;biosensors 这篇论文提出了一种基…

java数据结构与算法刷题-----LeetCode172. 阶乘后的零

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 数学&#xff1a;阶乘的10因子个数数学优化:思路转变为求5的倍数…

JQuery ajax请求

实现卡号绑定功能 通过 jQuery ajax 请求用户列表数据。 API 接口地址 卡号列表 js/cardnolist.json 接口响应示例 补全 index.js 中空缺代码&#xff0c;实现用户输入完卡号与密码后&#xff0c;与 ajax 请求到的卡号数据进行比对&#xff0c;当卡号和密码匹配成功时&a…

使用 Docker 部署 Linux-Command 命令搜索工具

1&#xff09;介绍 Linux-Command GitHub&#xff1a;https://github.com/jaywcjlove/linux-command Linux-Command 仓库搜集了 580 多个 Linux 命令&#xff0c;是一个非盈利性的仓库&#xff0c;生成了一个 Web 网站方便使用&#xff0c;目前网站没有任何广告&#xff0c;内…

JVM参数列表

-client :设置JVM使用client模式,特点启动较快(神机不明显(I5/8G/SSD)) -server :设置JVM使用server模式。64位JDK默认启动该模式 -agentlib:libname[options] :用于加载本地的lib -agentlib:hprof :用于获取JVM的运行情况 -agentpath:pathnamep[options] :加载制定路径的本…

共享内存详解

共享内存是操作系统在内存中开辟一块空间&#xff0c;通过页表与共享区建立映射关系&#xff0c;使两个进程看到同一份资源&#xff0c;实现进程间通信。 1、创建共享内存 参数&#xff1a;第一个参数为key&#xff0c;一般使用ftok()函数生成&#xff0c;key值不能冲突&#…

副业天花板流量卡推广,小白也可轻松操作

在如今的互联网时代&#xff0c;手机已经不仅仅是一款工具&#xff0c;更像是我们生活中的一部分&#xff0c;那么手机卡也是必需品&#xff0c;但存在的问题就是:很多手机卡的月租很贵&#xff0c;流量也不够用。所以大家都在寻找一个月租低&#xff0c;流量多的卡&#xff0c…

Java-Doc

Java-Doc javdoc命令是用来生成自己的API文档的 参数信息&#xff1a;author作者名version版本号since知名需要最早使用的jdk版本param参数名return返回值情况throws异常抛出情况 1.参数信息的使用&#xff1a; 未完待续... ...

【好消息】思维100活动历年真题模拟题700多道上线了,供反复吃透

今天是星期五&#xff0c;距离4月20日举办的上海小学生 2024年春季思维100活动线上比赛还有8天的时间&#xff0c;明天、后天的周末是可以用来备考的大块时间&#xff0c;报名了的同学要充分利用了。 为了帮助各位小朋友了解思维100活动的历年考试真题、官方发布的参考样题&…

【数组】5螺旋矩阵

这里写自定义目录标题 一、题目二、解题精髓-循环不变量三、代码 一、题目 给定⼀个正整数 n&#xff0c;⽣成⼀个包含 1 到 n^2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的正⽅形矩阵。 示例: 输⼊: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ] 二、解题精髓…

docker最简单教程(使用dockerfile构建环境)

一 手里有的东西 安装好的docker+dockerfile 二 操作 只需要在你的dockerfile文件下执行命令 docker build -t="xianhu/centos:gitdir" . 将用户名、操作系统和tag进行修改就可以了,这就相当于在你本地安装了一个docker环境,然后执行 docker run -it xianhu/ce…

阿里云4核16G服务器可以用来做什么?

阿里云4核16G服务器可以用来做什么&#xff1f;可用来搭建游戏服务器&#xff0c;阿里云4核16G服务器10M带宽30元1个月、90元3个月&#xff0c;优惠活动 aliyunfuwuqi.com/go/youhui 阿里云4核16G服务器可以用来做什么&#xff1f;除了搭建游戏服务器&#xff0c;还可以用来哪…

DVWA靶场的下载与搭建

目录 什么是靶场 DVWA靶场下载 下载地址 安装 什么是靶场 靶场就是人为提供的带有安全漏洞的服务&#xff0c;每一个学习者都可以在本地快速搭建来实操&#xff0c;回溯漏洞的发生原理以及操作方式。DVWA靶场呢就是一个可以通过浏览器访问的拥有可视化页面的web靶场。 DVW…

PostgreSQL入门到实战-第二十一弹

PostgreSQL入门到实战 PostgreSQL中表连接操作(五)官网地址PostgreSQL概述PostgreSQL中RIGHT JOIN命令理论PostgreSQL中RIGHT JOIN命令实战更新计划 PostgreSQL中表连接操作(五) 使用PostgreSQL RIGHT JOIN连接两个表&#xff0c;并从右表返回行 官网地址 声明: 由于操作系统…

vue3实现时钟效果

鼬鼬鼬鼬鼬被提需求了&#xff01;&#xff01;&#xff01; 产品&#xff1a;你学什么的&#xff1f; 我&#xff1a;跟CV有点关系 产品&#xff1a;control C加control V是吧 我&#xff1a;对对对 效果 时间实时变化&#xff1a; 页面部分 <template><div clas…

性能分析-数据库(安装、索引、sql、执行过程)与磁盘知识(读、写、同时读写、内存速度测试)

数据库 数据库&#xff0c;其实是数据库管理系统dbms。 数据库管理系统&#xff0c; 常见&#xff1a; 关系型数据库&#xff1a; mysql、pg、 库的表&#xff0c;表与表之间有关联关系&#xff1b; 表二维表统一标准的SQL&#xff08;不局限于CRUD&#xff09;非关系型数据…