【C语言】递归复杂度与链表OJ之双指针

【C语言】递归复杂度与链表OJ之双指针

🔥个人主页大白的编程日记

🔥专栏数据结构


文章目录

  • 【C语言】递归复杂度与链表OJ之双指针
    • 前言
    • 一.递归复杂度
      • 1.1递归时间复杂度
      • 1.2递归空间复杂度
    • 二.链表OJ之双指针
      • 2.1倒数第K个节点
      • 2.2链表的中间节点
      • 2.3反转链表
      • 2.4回文链表
      • 2.5相交链表
      • 双指针法
    • 后言

前言

哈喽,各位小伙伴大家好!今天我们继续深入探讨递归的复杂度和链表OJ常见的双指针法。话不多说,咱们进入正题!向大厂冲锋!

一.递归复杂度

1.1递归时间复杂度

前面我们讲的复杂度没有涉及到递归,那递归的复杂度又该如何计算呢?

// 计算阶乘递归Fac的时间复杂度?
long long Fac(size_t N)
{if(0 == N)return 1;return Fac(N-1)*N;
}


之前我们都是在一个函数中算时间算复杂度,但是递归会自己调用自己,所以递归的时间复杂度计算就需要把每次函数调用次数累加起来。

那我们现在修改一下代码,现在的时间复杂度又是多少呢?

// 计算阶乘递归Fac的时间复杂度?
long long Fac(size_t N)
{if (0 == N)return 1;for (int i = 0; i < N; i++){;}return Fac(N - 1) * N;
}


函数的调用次数不变,每次函数调用的复杂度改变。将每次函数调用的消耗相加
,时间复杂度函数为等差数列。大O渐进表示法算出O(N^2)。

结论:递归时间复杂度==所有递归递归调用次数累加。

现在我们再来计算一下斐波那契数列的时间复杂度。

// 计算斐波那契递归Fib的时间复杂度?
long long Fib(size_t N)
{if(N < 3)return 1;return Fib(N-1) + Fib(N-2);
}

这里我们需要画出递归展开图,然后发现调用次数是等比数列。
再用错位相减法计算调用次数即可。实际调用次数没那么多。
但是也是O(2^N)的量级。

1.2递归空间复杂度

那递归的复杂度又该如何计算呢?

  • 阶乘
    递归会调用函数,每次调用函数都会开辟栈帧。
    所以递归的空间复杂度是函数调用的次数。
// 计算阶乘递归Fac的空间复杂度?
long long Fac(size_t N)
{if(N == 0)return 1;return Fac(N-1)*N;
}

  • 斐波那契数列
// 计算斐波那契递归Fib的空间复杂度?
long long Fib(size_t N)
{if(N < 3)return 1;return Fib(N-1) + Fib(N-2);
}

斐波那契数列的递归是双倍递归,那他的空间复杂度该如何计算呢?

因为函数栈帧会重复利用,所以斐波那契数列的空间复杂度就是O(N)。

二.链表OJ之双指针

2.1倒数第K个节点

  • 题目
    倒数第k个节点

  • 思路分析


我们先让快慢指针拉开k步,当快指针到NULL节点,慢指针就是倒数第K个节点。

  • 代码
typedef struct ListNode ListNode;
int kthToLast(struct ListNode* head, int k)
{ListNode* slow,*fast;slow=fast=head;while(k--){fast=fast->next;}while(fast){fast=fast->next;slow=slow->next;}return slow->val;
}

2.2链表的中间节点

  • 题目
    链表的中间节点
  • 思路分析
    我们可以定义两个指针,一个每次走一步,一个每次走两步。

这就是我们的快慢指针。两个指针走的路程是2倍关系,当快指针走完时,慢指针也走了快指针的一半路程。

  • 代码
 typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head){//创建快慢指针struct ListNode* slow;struct ListNode* fast;slow=fast=head;while(fast&&fast->next){fast=fast->next->next;slow=slow->next;}//此时slow指向中间节点return slow;}

2.3反转链表

  • 题目
    反转链表
  • 思路
  • 我们创建三个节点指针n1,n2,n3。n1刚开始指向NULL,n2指向头节点,n3保存n2的下一个几点。每次都让n2指向n1,然后n1移动到n2,n2移动到n3.n3向后移动。当n2走到尾节点就完成反转。
  • 代码
 typedef struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head) {if(head==NULL)return NULL;ListNode* n1=NULL;ListNode* n2=head;ListNode* n3=head->next;while(n2){n2->next=n1;n1=n2;n2=n3;if(n3)n3=n3->next;}return n1;
}

2.4回文链表

  • 题目
    回文链表

  • 思路

  • 我们先找到中间节点,反转以中间节点为头节点的子链表。然后分别从头节点和中间节点开始遍历,一一对比,当中间节点走到NULL时,说明是回文链表。
    在这里插入图片描述

  • 代码

typedef struct ListNode ListNode;struct ListNode* reverseList(struct ListNode* head)
{//创建三个指针ListNode *n1,*n2,*n3;n1=NULL;n2=head;if(n2)n3=n2->next;while(n2){n2->next=n1;n1=n2;n2=n3;if(n3)n3=n3->next;}return n1;
}
struct ListNode* middleNode(struct ListNode* head){//创建快慢指针struct ListNode* slow;struct ListNode* fast;slow=fast=head;while(fast&&fast->next){fast=fast->next->next;slow=slow->next;}//此时slow指向中间节点return slow;}
bool isPalindrome(struct ListNode* head) 
{ListNode* mid=middleNode(head);//找到中间节点ListNode* reverse=reverseList(mid);//反转后面节点ListNode*pcur=head;while(reverse){if(pcur->val!=reverse->val)//匹配{return false;break;}reverse=reverse->next;//移动pcur=pcur->next;}return true;
}

2.5相交链表

  • 题目
    相交链表

  • 思路

  • 判断相交
    分别遍历两个链表到尾节点,判断尾节点地址是否相等。相等就相交

  • 找交点
    让长链表走两链表长度的差距步,此时两节点距离交点差距相等。两节点同时往后遍历,相遇的位置就是交点。

  • 代码
typedef struct ListNode ListNode;
struct ListNode* getIntersectionNode(struct ListNode* headA,struct ListNode* headB) {int lena = 0, lenb = 0;ListNode* pa = headA;ListNode* pb = headB;while (pa->next){lena++;pa = pa->next;//遍历统计}while (pb->next){lenb++;pb = pb->next;//遍历统计}if (pb != pa) {return NULL;}ListNode* pshort = headA;ListNode* plong = headB;if (lena > lenb) //假设法{plong = headA;pshort = headB;}int tmp = abs(lena - lenb);while (tmp--) {plong = plong->next;//走差距步}while (plong!=pshort){pshort = pshort->next;plong = plong->next;}return plong;
}

双指针法

大家发现这些题目都会用到两个指针解决问题,这就是我们说的双指针法,具体如何运用双指针,得看具体题目灵活运用。

后言

这就是递归的复杂度和链表常见OJ。今天就分享到这里,感谢大家耐心垂阅。咱们下期见!拜拜~
在这里插入图片描述

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

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

相关文章

FastJson与JackSon 的碰撞。服务发送方与服务接收方字段不一致问题

情景再现 对接文档人家要求字段为 于是乎 咱就在服务的发送方定义参数字段为 服务接收方接收的类型为 later。。。。。 服务接收方接收到的参数字段 就不变成了fOrgId。跟外部系统对接就提示参数错误 原因 &#xff1a;lombok 在做set get的时候自动 无论你字段的首字母是大…

我与Python的一夜情

期末突击看这篇才够味&#xff01; 环境搭建 首先就是相关工具的安装&#xff0c;直接搜就好&#xff0c;但是还是贴个网址吧&#xff1a; Welcome to Python.orghttps://www.python.org/ 然后就是根据自己的系统选择咯&#xff1a; 谁能闲来无事送我个mac玩玩 Windows的一…

哈喽GPT-4o——对GPT-4o 写论文的思考与看法

目录 几小时即可完成一份1万字论文的编写1、改写降重2、同义词替换降重3、避免连续相同4、缩写扩写降重5、关键词汇替换降重6、句式变换降重7、逻辑重组8、综合改写9、数据呈现方式变更10、概念解释降重 大家好&#xff0c;我是哪吒。 在ChatGPT4o对话框中输入&#xff1a;写一…

遥控玩具车电机驱动应用中的双H桥驱动芯片

遥控玩具车的基本工作原理是通过无线电遥控器发送信号&#xff0c;这些信号被玩具车内的接收器接收并解码&#xff0c;从而控制玩具车的运行。根据车身外型的不同&#xff0c;可以分为&#xff1a;普通的私家房车、越野车、货柜车、翻斗车等等。遥控器的操作&#xff0c;如前进…

测试 halcon measure_projection 算子

期望结果完全相同&#xff0c;但是下面的测试结果和halcon的差值如下: [0.132838, 0.231991, 0.265157, 0.296903, 0.0998573, 0.165907, 0.230686, 0.130266, 0.0977104, 0.197109, 0.198173, 0.197086, 0.190943, 0.177665, 0.163521, 0.146541, 0.161362, 0.166666, 0.2281…

NG32031单片机串口初始化

目录 1. 串口基础 2. 串口配置步骤 3. N32G031串口初始化示例 3.1开启时钟 3.2 配置GPIO 3.3 配置USART 3.4 使能中断&#xff08;如果需要&#xff09; 3.5. 示例代码 4. 调试和验证 5. 注意事项 6. 额外功能 NG32G031单片机的串口&#xff08;UART&#xff09;通常…

理解Python的元类

1.type()函数 type 函数是一个内置函数&#xff0c;用来获取一个对象的类型。它可以接受一个参数&#xff0c;返回这个参数的数据类型。type也可以用来创建类&#xff0c;type就是元类 x333 list["ab"] tuple (1, "a", True, 3.14) dict {name: Alice,…

这4款国产软件,因为太良心好用,甚至被误认为是外国人开发的

说起国产软件&#xff0c;大家总是容易给它们打上“流氓、要钱、广告满天飞”的标签&#xff0c;其实&#xff0c;有些小众的软件超级好用&#xff0c;功能强大又不耍流氓&#xff0c;真心不该被一棍子打死。 1、sunlight studio Sunlight Studio是一个开源、免费、无广告的硬…

从云端到终端:青犀视频汇聚/融合平台的视频接入方式与场景应用

一、青犀视频汇聚/融合平台 由TSINGSEE青犀视频研发的EasyCVR智能融合/视频汇聚平台基于“云-边-端”一体化架构&#xff0c;支持视频汇聚、融合管理&#xff0c;兼容多协议&#xff08;GA/T1400/GB28181/Onvif/RTSP/RTMP/海康SDK/Ehome/大华SDK/宇视SDK等&#xff09;、多类型…

你的职业规划就是面向贫穷的规划

如果你觉得作者的文章还有点用,请记得点赞 + 关注 说一个扎心的事实,就是我们绝大多数人的职业规划基本上都是错误的,都是面向贫穷的规划。 因为绝大多数人的职业规划都是打工人的职业规划,这种规划除了很少部分人最终能成为企业高管,实现层级跃迁外,绝大多数人在大多数…

Java17 --- RabbitMQ之常规使用

目录 一、实现消息可靠性投递 1.1、消息生产者端确认机制 1.2、备份交换机 1.3、消费端确认机制 二、消费端限流设置 三、消息超时设置 3.1、从队列设置全局超时时间 3.2、设置消息本身超时时间 四、死信 4.1、消费端拒绝接收消息 4.1.1、创建死信交换机与队列 …

LangChain入门学习笔记(一)——Hello World

什么是LangChain LangChain是一个开源&#xff08;github repo&#xff09;的大语言模型应用开发框架&#xff0c;提供了一整套的工具、方法和接口去帮助程序员构建基于大语言模型的端到端应用。LangChain是长链&#xff08;long chain&#xff09;的意思&#xff0c;它的一个…

Linux驱动开发笔记(八)输入子系统

文章目录 前言一、输入子系统1. 子系统的引入2. 组成部分3. 事件处理流程4. 相关数据结构 二、程序编写1. 相关API函数1.1 input_allocate_device ( )1.2 input_free_device ( )1.3 input_register_device ( )1.4 input_unregister_device ( )1.5 input_event ( )1.6 input_rep…

Prometheus写入influxDB:中间件remote_storage_adapter

Prometheus写入influxDB&#xff1a;中间件remote_storage_adapter prometheus默认采用的是本地磁盘做数据存储&#xff0c;本地存储的优势就是运维简单但是缺点就是无法海量的metrics持久化和数据存在丢失的风险,数据写入可能造成wal文件损坏导致采集数据无法再写入的问题。 …

【嵌入式DIY实例】-Nokia 5110显示DS18B20传感器数据

Nokia 5110显示DS18B20传感器数据 文章目录 Nokia 5110显示DS18B20传感器数据1、硬件准备2、代码实现本文将介绍如何使用 ESP8266 NodeMCU 板和 DS18B20 数字温度传感器实现简单的温度测量站。 NodeMCU 微控制器 (ESP8266EX) 从 DS18B20 传感器读取温度值,并将其打印在诺基亚 …

Nginx部署Vue项目css文件能加载但是不生效

目录 问题描述问题解决 问题描述 Nginx部署打包后的Vue项目css文件能加载但是不生效&#xff0c; 问题解决 查看响应标头&#xff0c;发现不对劲&#xff0c; Content-Type: text/plain正确的应该是 Content-Type: text/css根本原因是nginx没有告诉浏览器正确的文件类型 所…

Postman接口测试/接口自动化实战教程

一、API 自动化测试 Postman 最基本的功能用来重放请求&#xff0c;并且配合良好的 response 格式化工具。 高级点的用法可以使用 Postman 生成各个语言的脚本&#xff0c;还可以抓包&#xff0c;认证&#xff0c;传输文件。 仅仅做到这些还不能够满足一个系统的开发&#x…

Python学习打卡:day05

day5 笔记来源于&#xff1a;黑马程序员python教程&#xff0c;8天python从入门到精通&#xff0c;学python看这套就够了 目录 day538、函数的初体验39、函数的基础定义语法函数的定义注意事项 40、函数的基础定义案例练习41、函数的传入参数42、函数的传入参数案例练习——升…

毕业年薪30W起!25届最近5年浙江大学自动化考研院校分析

浙江大学 目录 一、学校学院专业简介 二、考试科目指定教材 三、近5年考研分数情况 四、近5年招生录取情况 五、最新一年分数段图表 六、历年真题PDF 七、初试大纲复试大纲 八、学费&奖学金&就业方向 一、学校学院专业简介 二、考试科目指定教材 1、考试科目…

揭秘招生简章的制作方法

一年一度的招生季即将来临&#xff0c;各大院校纷纷摩拳擦掌&#xff0c;准备迎接新的学子。对于学校而言&#xff0c;招生简章是其对外宣传的重要窗口&#xff0c;它直接关系到学校的招生效果和声誉。那么&#xff0c;如何制作一份既吸引人又实用的招生简章呢&#xff1f;下面…