秋招之路-链表面试题集合(一)

2024-08-27 01:38

本文主要是介绍秋招之路-链表面试题集合(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

[图]program 2019-07-22

这是 herongwei 的第 79 篇原创

阅读本文大概需要 6.66 分钟

前言

链表是最基本的数据结构,面试官也常常用链表来考察面试者的基本能力,链表的操作也离不开指针,指针又很容易导致出错。综合多方面的原因,链表题目在面试中占据着很重要的地位。这里总结常见的链表面试题,希望对你有所帮助!

今天的题目

1、单链表翻转

2、输入两个单链表,找出它们的第一个公共结点

3、归并有序的两个链表(递归和非递归)

1、定义

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。

每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快,但是查找一个节点或者访问特定编号的节点则需要 O(n) 的时间,而线性表和顺序表相应的时间复杂度分别是 O(logn) 和 O(1)。 

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

2、单链表翻转

参考代码:

/*//当前节点是head,pre为当前节点的前一节点,next为当前节点的下一节点//需要pre和next的目的是让当前节点从pre->head->next1->next2变成pre<-head next1->next2//即pre让节点可以反转所指方向,但反转之后如果不用next节点保存next1节点的话,此单链表就此断开了//所以需要用到pre和next两个节点//1->2->3->4->5//1<-2<-3 4->5//1.做循环,如果当前节点不为空的话,始终执行此循环,此循环的目的就是让当前节点从指向next到指向pre//如此就可以做到反转链表的效果//先用next保存head的下一个节点的信息,保证单链表不会因为失去head节点的原next节点而就此断裂//2.保存完next,就可以让head从指向next变成指向pre了//3.head指向pre后,就继续依次反转下一个节点//4.让pre,head,next依次向后移动一个节点,继续下一次的指针反转
*/
class Solution {
public:ListNode* ReverseList(ListNode* pHead) {ListNode* pReversedHead = nullptr;ListNode* pCur = pHead;ListNode* pPre = nullptr;while(pCur != nullptr) {ListNode* pNext = pCur->next;//链断开之前一定要保存断开位置后边的结点if(pNext == nullptr) //当next为空时,说明当前结点为尾节点pReversedHead = pCur;pCur->next = pPre;pPre = pCur;pCur = pNext;}return pReversedHead;}
};//栈存储
class Solution {
public:ListNode* ReverseList(ListNode* pHead) {std::stack<int> st;ListNode* p = pHead;ListNode* q = pHead;while (p) {st.push(p->val);p = p->next;}while (q) {q->val = st.top();st.pop();q = q->next;}return pHead;}
};

3、输入两个单链表,找出它们的第一个公共结点

参考代码

/*
一般两种思路
思路一:找出 2 个链表的长度,然后让长的先走两个链表的长度差,然后再一起走(因为 2 个链表用公共的尾部)
思路二:不用计算长度:
设 A 的长度为 a + c,B 的长度为 b + c,其中 c 为尾部公共部分长度,可知 a + c + b = b + c + a。
当访问 A 链表的指针访问到链表尾部时,令它从链表 B 的头部开始访问链表 B;同样地,当访问 B 链表的指针访问到链表尾部时,令它从链表 A 的头部开始访问链表 A。这样就能控制访问 A 和 B 两个链表的指针能同时访问到交点。
如果不存在交点,那么 a + b = b + a,以下实现代码中 l1 和 l2 会同时为 null,从而退出循环。
*/class Solution {
public:ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) {int len1 = findListLenth(pHead1);int len2 = findListLenth(pHead2);if(len1 > len2){pHead1 = walkStep(pHead1,len1 - len2);}else{pHead2 = walkStep(pHead2,len2 - len1);}while(pHead1 != nullptr){if(pHead1 == pHead2) return pHead1;pHead1 = pHead1->next;pHead2 = pHead2->next;}return nullptr;}int findListLenth(ListNode *pHead){if(pHead == nullptr) return 0;int sum = 1;while(pHead = pHead->next) sum++;return sum;}ListNode* walkStep(ListNode *pHead, int step){while(step--){pHead = pHead->next;}return pHead;}
};class Solution {
public:ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) {ListNode *p1 = pHead1;ListNode *p2 = pHead2;while(p1!=p2){p1 = (p1==nullptr ? pHead2 : p1->next);p2 = (p2==nullptr ? pHead1 : p2->next);}return p1;}
};

如果只是判断是否存在交点,那么就是另一个问题,即 编程之美 3.6 的问题。有两种解法:

1、把第一个链表的结尾连接到第二个链表的开头,看第二个链表是否存在环;

2、或者直接比较两个链表的最后一个节点是否相同。

4、归并两个有序的链表

思路类似归并排序。

参考代码

//1、递归
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution {
public:ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {if (l1 == nullptr) return l2;if (l2 == nullptr) return l1;if (l1->val < l2->val) {l1->next = mergeTwoLists(l1->next, l2);return l1;} else {l2->next = mergeTwoLists(l1, l2->next);return l2;}}
};
//2、非递归
class Solution {
public:ListNode* mergeTwoLists(ListNode* l1, ListNode* l2){ListNode * head = new ListNode(0);ListNode * tmp = head;while(l1 != nullptr && l2 != nullptr) {if(l1->val < l2->val) {tmp->next = l1;l1 = l1->next;} else {tmp->next = l2;l2 = l2->next;}tmp = tmp->next;}if(l1 != nullptr) tmp->next = l1;if(l2 != nullptr) tmp->next = l2;return head->next;//pointer to the start of tmp is returned}
};

如果觉得写得不错,欢迎点好看,转发哦~

推荐阅读

碎片化时间真的适合学习吗?

秋招之路-UDP 和 TCP 核心知识总结

秋招之路-关于进程、线程、协程的一些见解

认真的人,自带光芒!

原创不易

点个在看呗

这篇关于秋招之路-链表面试题集合(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1110269

相关文章

2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题

题库来源:安全生产模拟考试一点通公众号小程序 2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题是由安全生产模拟考试一点通提供,流动式起重机司机证模拟考试题库是根据流动式起重机司机最新版教材,流动式起重机司机大纲整理而成(含2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题参考答案和部分工种参考解析),掌握本资料和学校方法,考试容易。流动式起重机司机考试技

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

uva 11178 计算集合模板题

题意: 求三角形行三个角三等分点射线交出的内三角形坐标。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

Java基础回顾系列-第六天-Java集合

Java基础回顾系列-第六天-Java集合 集合概述数组的弊端集合框架的优点Java集合关系图集合框架体系图java.util.Collection接口 List集合java.util.List接口java.util.ArrayListjava.util.LinkedListjava.util.Vector Set集合java.util.Set接口java.util.HashSetjava

【408数据结构】散列 (哈希)知识点集合复习考点题目

苏泽  “弃工从研”的路上很孤独,于是我记下了些许笔记相伴,希望能够帮助到大家    知识点 1. 散列查找 散列查找是一种高效的查找方法,它通过散列函数将关键字映射到数组的一个位置,从而实现快速查找。这种方法的时间复杂度平均为(

【秋招笔试】9.07米哈游秋招改编题-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收集 100+ 套笔试题,笔试真题 会在第一时间跟新 🍄 题面描述等均已改编,如果和你笔试题看到的题面描述

【电子通识】半导体工艺——保护晶圆表面的氧化工艺

在文章【电子通识】半导体工艺——晶圆制造中我们讲到晶圆的一些基础术语和晶圆制造主要步骤:制造锭(Ingot)、锭切割(Wafer Slicing)、晶圆表面抛光(Lapping&Polishing)。         那么其实当晶圆暴露在大气中或化学物质中的氧气时就会形成氧化膜。这与铁(Fe)暴露在大气时会氧化生锈是一样的道理。 氧化膜的作用         在半导体晶圆

java集合的概述

集合就是一个容器,我们可以把多个对象放入的容器中。就像水杯(假设容量可以不断扩大)一样,你可以往水杯中不断地添加水,既然是水杯,你就不能往里添加沙子,也就是说集合中添加的对象必须是同一个类型的(引用类型,而不能是基本类型)。 看到集合的介绍会让我们的想起数组,那么集合和数组有什么区别呢? 首先,数组的大小是固定的,而集合理论上大小是不限的。 其次,数组既可以存储基本数据类型的数据,也可以存储

2018秋招C/C++面试题总结

博主从8月中旬开始大大小小面试了十几家公司,至今也许是告一段落吧,希望后面会有好结果,因此总结记录一些C/C++方向常见的问题。和大家一起学习! 参考了互联网的各种资源,自己尝试归类整理,谢谢~ 一、C和C++的区别是什么? C是面向过程的语言,C++是在C语言的基础上开发的一种面向对象编程语言,应用广泛。 C中函数不能进行重载,C++函数可以重载 C++在C的基础上增添类,C是一个结构