【数据结构】链表OJ面试题(题库+解析)

前言

还不清楚链表的码喵们可以看看前篇关于链表的详解

http://t.csdnimg.cn/X6t6P


1.链表面试题

既然已经懂得了链表该如何实现,那么现在就趁热打铁开始练习!这里给码喵们整理了相对不错的一些OJ题来练习

1. 删除链表中等于给定值 val 的所有结点。

 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

思路:遍历整个表,访问每个表的值并且删除再将next的指针指向下一个节点

此题比较简单,但是有几个要点来考虑:

  1. 如果第一位是需要删除的数

  2. 执行删除时要如何保存此值的地址来进行空间释放

  3. 等于val值执行删除

  4. 不等于val的值执行向下遍历

附原代码

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* removeElements(struct ListNode* head, int val){struct ListNode *tail=head;struct ListNode *prev=NULL; //用于记录节点在free掉的时候避免找不到while(tail!=NULL)   //不为尾节点向后遍历{if(tail->val == val)    //如果第一位是需要删除的数{if(tail==head){head=tail->next;free(tail);tail = head;}else                //执行删除节点,并且free掉空间避免空指针或溢出{prev->next = tail->next;free(tail);tail = prev->next;}}else{prev = tail;tail=tail->next;}}return head;}

2. 反转一个单链表。

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

本题有些难度,但是掌握好方法后类似的题就能做到运筹帷幄(决胜千里之外)

做题的要点是画图

万事开头难,掌握方法微妙,刚开始我做这题的时候想的是把他变成一个循环指针然后再标记头指针并且实现反转,不知道这样的办法大家有没有试过哈哈,现在我们来用更简单的方法吧。

我们来指定三个指针,前两个指针用于将前一个的指针记录并且连接,第三个指针负责向后遍历直到为空

方法

定义三个指针

n1滞空用于将头指针变成新链表的尾指针,所以滞空

n2 ,n3向后遍历

首先我们让n2的下一个结点指向n1,实现第二和第一个节点的相连,再让n2=n3改变n2的地址,再让n3向下一个节点移动

n3再向下一个节点移动,之后循环到n2为空地址,就完成了所有节点的反转了。

注意要点:

  1. 链表初始值为空要怎么处理
  2. 链表的n2最终到哪里才算结束反转
  3. 指针n3的下一个节点若为空怎么办(不能赋值否则会越界)

附原代码

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* reverseList(struct ListNode* head) {struct 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;
}

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

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

这就要运用上非常巧妙的方法了,既然上一题我们用到了三个指针,这道题我们也用指针来做,但是只用两个指针就好

方法

我们定义两个指针都在头节点向后遍历,但是一个节点一次走一步,一个节点一次走两步

当tail走到最后的节点时,head节点刚好返回的就是中间值。

注意要点:

  1. tail走两步,head走一步,返回head的地址就是中间的地址
  2. 如果tail走到尾要怎么处理

附源代码

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* middleNode(struct ListNode* head) {struct ListNode* tail = head;while(tail->next){head=head->next;tail=tail->next;if(tail->next==NULL){//head=head->next;}elsetail=tail->next;}return head;// struct ListNode* tail = head;// int count=0;// while(tail->next)// {//     count++;//     tail = tail->next;// }// if(count%2!=0)// {//     count=(count+1)/2;// }// else// count/=2;// while(count--)// {//     head=head->next;// }// return head;
}

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

链表中倒数第k个结点_牛客题霸_牛客网

此题是上一题的升级版,方法相似,上一题是相对移动,本体是相对距离再移动

方法

这次我们定义两个指针,一个first指针先向前走k步,之后在first和tail指针一起向前走,直到first指针走到结尾,返回tail指针

注意要点

  1. first指针走到尾该如何处理
  2. 空的链表该如何处理
  3. k等于链表的长度该返回什么值(返回第一个节点)
  4. k大于链表的长度该返回什么值(不是我想思考,是nt牛客的测试用例真有这几点,吃饱撑着)

附源代码

/*** struct ListNode {*	int val;*	struct ListNode *next;* };*//*** * @param pListHead ListNode类 * @param k int整型 * @return ListNode类*/
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k)
{if (pListHead == NULL)	//链表为空直接返回NULL{return pListHead;}struct ListNode* first = pListHead;struct ListNode* tail = pListHead;while (first->next)	//直到first走到尾{while (k > 0 && first->next)	//k没减到0并且first还没走到尾进入循环{k--;	//这里用k自减1来进行k次循环的实现(k=0侧不执行)first = first->next;//if (first->next == NULL && k > 0)//{//	return NULL;//}}if (first->next == NULL&&k==1)		//当k减到1并且first已经走到尾{return tail;				//我们就可以直接返回tail的值,这就是返回第一个节点}else if(k>1)					//如果first到达尾,并且k还大于1,那就是k大于整个链表长度的情况{return NULL;				//直接返回NULL}tail = tail->next;		//tail向下走一步first = first->next;	//frist向下走一步}//tail=tail->next;return tail->next;
}// int count = k;// while(first->next)// {//     first=first->next;// }//     int len = count;// while(tail->next)// {//     while(len--)//     {//         tail=tail->next;//     }//     if(tail!=first)//     {//         len = count;//     }//     else //     {//         return pListHead->next;//     }//     pListHead = tail;// }// return 0;// write code here

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

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

方法

照图来看,我们可以很明显的知道我们可以把新的数据放入“新的“链表,这里的引号,意思是这种合并的题目,我们可以不创建新的空间,因为链表的特性,就是每个都是一块独立的空间,而我们就可以把这些表重新”排序“使之形成一个新的链表,而这里的排序方法就是:比较较小值,尾插入新表中。

新建两个链表

当新表为空时,将较小值(list1)的地址直接赋值,并且更新list1使之向后走,这里因为list1、list2相等,所以随便取一个就行。

依此类推,list2、list1对比时,list2较小,将list2赋值list3,同时更新。

最后当其中一个表(list2)所有值都赋值给新表后,在把另一个表的所有值直接尾插到新表就OK了,不管另一个表后有多少个值,都可以直接尾插并且完成链表的合并

之后返回我们记录的tail就完成了(真是功夫不负有心人啊)

注意要点:

  1. 初始创建表时,首节点为空,我们要让它赋值原表的地址,应该分类讨论
  2. 注意各表的更新
  3. 当其中一个表中所有的值都赋值完毕,另外一个表就可以全部尾插入新表中
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) 
{struct ListNode* list3=NULL;struct ListNode* tail=NULL;if(list1==NULL){return list2;   //若其中一个表为空则返回另一个表}if(list2==NULL){return list1;   //若其中一个表为空则返回另一个表}while(list1&&list2){if(list1->val>list2->val)   //返回小的值{if(list3==NULL){tail=list3=list2;   //如果新链表没有头则把较小值的地址赋值}else{list3->next = list2;    //新链表的下一个节点指向较小值list3=list3->next;      //更新新链表}list2=list2->next;          //更新已被赋值的较小值链表首地址}else if(list1->val<list2->val){if(list3==NULL){tail=list3=list1;   //如果新链表没有头则把较小值的地址赋值}else{list3->next = list1;list3=list3->next;}list1=list1->next;}else                //两值相同则赋值其中一个链表的首地址{if(list3==NULL){tail=list3=list1;   //如果新链表没有头则把较小值的地址赋值}else{list3->next = list1;list3=list3->next;}list1=list1->next;}}   if(list1)       //其中一个表全部赋值完毕,侧再把另一个表的剩下值尾插到新表{list3->next=list1;return tail;} else if(list2){list3->next=list2;return tail;}else{return tail;}}

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

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

8. 输入两个链表,找出它们的第一个公共结点。OJ链接

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

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

相关文章

JAVA和C#怎么开发SECS/GEM:recipe配方处理 S7F1、S7F19

recipe是什么内容呢&#xff1f; recipe是机台加工不同产品时的对应程式&#xff0c;指的是由制造工程师提前在机台上设置&#xff0c;并且EAP控制生产时会自动根据货的类型选择并控制机台按照制造工程师提前设置的方式进行加工。 recipe也称为配方&#xff0c;配方是怎么来的…

【项目管理】立项管理

一、前言 对于甲方的立项&#xff1a;需求调研二编写项目申请书一可行性研究&#xff08;机会、初步、详细&#xff09;一项目论证一项目评估一评审获得批准一发布招标文件&#xff01;对于乙方的立项&#xff1a;看到招标文件一进行项目识别一可行性研究&#xff08;机会、初…

AtCoder Beginner Contest 338F - Negative Traveling Salesman【floyd+状态压缩dp】

原题链接&#xff1a;https://atcoder.jp/contests/abc338/tasks/abc338_f Time Limit: 6 sec / Memory Limit: 1024 MB Score: 500 points、 问题陈述 有一个有N个顶点和M条边的加权简单有向图。顶点的编号为 1 到 N&#xff0c;i/th 边的权重为 Wi​&#xff0c;从顶点 U…

CRF条件随机场学习记录

阅读建议 仔细阅读书[1]对应的序列标注章节&#xff0c;理解该方法面向的问题以及相关背景&#xff0c;然后理解基础的概念。 引言 威胁情报挖掘的相关论文中&#xff0c;均涉及到两部分任务&#xff1a;命名实体识别&#xff08;Named Entity Recognition&#xff0c;NER&a…

ECharts 图表嵌入表格样式的demo

心累。。。 如果条件允许&#xff0c;还是强烈建议 用 Echartshtml 来实现&#xff08;表格部分由 html 来弄&#xff09;。 这里是调研阶段&#xff0c;想看看 ECharts 原生能做到什么程度。 先贴上样图&#xff1a; 贴上完整代码&#xff1a; <!DOCTYPE html> <…

图的学习

图的基本概念和术语 图的定义&#xff1a;图是由顶点的有穷非空集合和顶点之间的边的集合组成的&#xff0c;G表示&#xff0c;V是图G中顶点的集合&#xff0c;E是图G中边的集合 无向图&#xff1a;任意两点的边都是无向边组成的图&#xff08;无向边&#xff1a;&#xff08…

助阵央视春晚直播间,德施曼智能锁携手小红书“大家的春晚”玩转除夕夜

2月9日大年三十当天&#xff0c;智能锁行业领军品牌德施曼&#xff0c;将助阵小红书“央视春晚直播间”&#xff0c;参与“大家的春晚”活动&#xff0c;在直播间陪14亿观众一起看春晚&#xff0c;聊春晚&#xff0c;玩转除夕夜。 每年的央视春晚&#xff0c;都是亿万观众翘首…

前端工程\模块化

前端工程\模块化&#x1f3ed; 本篇文章&#xff0c;学习记录于&#xff1a;尚硅谷&#x1f3a2;&#xff0c;紧接前文&#xff1a;邂逅Node.JS的那一夜→博客 无论是前端、后端、甚至非编程领域都有模块化的概念&#xff0c;只是不同的领域叫法不同&#xff0c;不过&#xf…

Qt程序打包发布方法

步骤一 程序变成Release版本&#xff0c;编译一下 然后会生成后缀为.exe的文件 文件位置在x64/Release/ 下 步骤二 按下电脑的winR&#xff0c;输入cmd 点击确定进入如下界面 输入 cd 你的文件夹地址按下回车 如图所示 输入 windeployqt *.exe(*指的是你的文件名) &…

银行数据仓库体系实践(8)--主数据模型设计

主数据区域中保留了数据仓库的所有基础数据及历史数据&#xff0c;是数据仓库中最重要的数据区域之一&#xff0c;那主数据区域中主要分为近源模型区和整合&#xff08;主题&#xff09;模型区。上一节讲到了模型的设计流程如下图所示。那近源模型层的设计在第2.3和3这两个步骤…

聊聊 Http 服务化改造实践

在微服务架构体系中远程 RPC 调用主要包括 Dubbo 与 Http 调用两个大类&#xff0c;由于 Dubbo 拥有服务注册中心&#xff0c;并且起服务的命名非常规范&#xff0c;使用包名.类名.方法名进行描述。 粉丝福利&#xff0c; 免费领取C/C 开发学习资料包、技术视频/项目代码&#…

解读4篇混合类型文件Polyglot相关的论文

0. 引入 Polyglot文件指的是混合类型文件&#xff0c;关于混合类型文件的基础&#xff0c;请参考文末给出的第一个链接&#xff08;参考1&#xff09;。 1. Toward the Detection of Polyglot Files 1.1 主题 这篇2022年的论文&#xff0c;提出了Polyglot文件的检测方法。虽…