链表面试题总结(二)
来源:互联网 发布:网络思想政治教育总结 编辑:程序博客网 时间:2024/06/05 02:54
昨天总结了一部分基础的面试题,有兴趣的小伙伴可以戳链接去看看链表面试题总结(一)。今天想要总结的是链表面试题的升级部分,关于链表带环部分和相交部分。
常见的面试题目:
- 合并两个有序链表, 合并后依然有序
- 求两个已排序单链表中相同的数据
- 判断单链表是否带环?若带环,求环的长度?求环的入口点?
- 判断两个链表是否相交,若相交,求交点。(假设链表不带环)
- 判断两个链表是否相交,若相交,求交点。(假设链表可能带环)
合并两个有序链表, 合并后依然有序
分析:首先它是一个有序链表,那么数据一定是规律的。我们创建新指针newHead用来保存合并后有序链表的头,用一个tail指针向后进行比较,指向新的节点。用tmp保存当前节点的信息,然后指针向后移动。直到其中一个链表被遍历完,直接用tail将另一个链表的后续部分链接起来。
SListNode* Merge(SListNode* l1, SListNode* l2) //合并两个有序链表,合并后依然有序{ if (l1 == NULL) return l2; if (l2 == NULL) return l1; SListNode* newHead; SListNode* tail; SListNode* tmp; if (l1->data < l2->data) newHead = tail = l1; else newHead = tail = l2; while ((l1!= NULL) && (l2 != NULL)) { if (l1->data < l2->data) { tmp = l1; l1 = l1->next; } else { tmp = l2; l2 = l2->next; } tail->next = tmp; tail = tmp; } if(l1) tail->next = l1; else tail->next = l2; return newHead;}
求两个已排序单链表中相同的数据
分析:题目已经告诉我们是有序链表,所以一定要把这个条件用好。和上面的题目类似,直接对两个节点的数据进行比较,如果不相等,就向后移动,谁小就移动谁;如果相等,就直接打印此出来,直到遍历整个链表。由于较简单,就不画图说明了。
void UnionSet(SListNode* l1, SListNode* l2) //求两个已排序单链表中相同的元素{ assert(l1 && l2); while (l1 && l2) { if (l1->data < l2->data) l1 = l1->next; else if (l1->data > l2->data) l2 = l2->next; else { printf("%d ", l1->data); l1 = l1->next; l2 = l2->next; } }}
判断单链表是否带环?若带环,求环的长度?求环的入口点?
1、判断单链表是否带环?
分析:先来判断一个链表是否带环,如果一个链表带环,它就没有尾节点,类似下图这种:
那么判断链表带环的问题就要从这里入手了,既然是一个环,那么肯定会在里面循环,所以就可以借鉴快慢指针问题了。定义一个快指针,一个慢指针,同时出发,如果可以相遇,那么就是环;如果不能相遇,则为非环链表。图示如下:
SListNode* IsCircle(SListNode* pHead) //判断一个链表是否带环{ SListNode* fast, *slow; fast = slow = pHead; while (fast && fast->next) { fast = fast->next->next; slow = slow->next; if (fast == slow) { return slow; } } return NULL;}
2、若带环,求环的长度
分析:如果判断为环了,定义一个计数器count,那么环的长度就是沿着这个环在走一遍,再次走到现在的位置时,count的值。
size_t GetCircle(SListNode* meetNode) //如果带环,求环的长度{ assert(meetNode); int count = 1; SListNode* cur = meetNode->next; while (cur != meetNode) { cur = cur->next; ++count; } return count;}
3、求环的入口点
分析:既然已经能确定是环,而且在第1问中,将相遇点返回了,那么我们就可以利用数学知识来求解入口点这个问题了。在这里,要说的方法还是快慢指针,这个题换成数学题,就变成了求相遇问题。下面用图来解释一下。
(关于为什么是一个走两步,一个走一步的原因:既然是要相遇,如果快指针走三步,它每次会跳过两个节点,慢指针一次只能走一步,这就可能会错过。快指针每次走两步的话,只会跳过一个节点,无论如何后都会和慢指针相遇。)
SListNode* GetEnter(SListNode* pHead, SListNode* meetNode) //求环的入口{ SListNode* cur = pHead; assert(cur && meetNode); while (cur && meetNode) { if (cur == meetNode) return meetNode; cur = cur->next; meetNode = meetNode->next; } return NULL;}
判断两个链表是否相交,若相交,求交点。(假设链表不带环)
1、判断两个链表是否相交
分析:如果两个链表相交,那么它应该如下图所示。根据它的结构特点,我们可以发现,如果两个链表相交,它的尾节点一定是相同的。也就是说当两个链表的尾节点相同时,它们一定是相交的。
SListNode* IsUnion(SListNode* l1, SListNode* l2) //判断是否相交{ assert(l1 && l2); while (l1->next) l1 = l1->next; while (l2->next) l2 = l2->next; if (l1 == l2) return l1; return NULL;}
2、若相交,求交点
分析:在链表中的相交相遇问题,貌似比较优的解法都是和快慢指针有关的。当然求交点,也是一样的。假设,两个链表一样长,那么它们的相交的判断方法就是在某处这两个节点的信息相同。好了,现在假设我们知道这两个链表的长度,让较长的那个先走两个链表长度之差步,那么接下来的处理方式就和一样长的链表的处理方式一样了。
SListNode* GetMeetNode(SListNode* l1, SListNode* l2) //如果相交,求交点{ int len1 = 1; int len2 = 1; SListNode* cur1 = l1; SListNode* cur2 = l2; while (cur1->next) { cur1 = cur1->next; ++len1; } while (cur2->next) { cur2 = cur2->next; ++len2; } size_t k = abs(len1 - len2); SListNode* longNode, *shortNode; if (len1 > len2) { longNode = l1; shortNode = l2; } else { longNode = l2; shortNode = l1; } while (k--) { longNode = longNode->next; } while (longNode != shortNode) { longNode = longNode->next; shortNode = shortNode->next; } return shortNode;}
判断两个链表是否相交,若相交,求交点。(假设链表可能带环)
其实这个题目和上面的那个比较相似,甚至说是上面的延伸。在这种情况下,我们只需要理清可能出现的情况,然后根据对应的情况进行分析。
上面这六种是满足题设要求的情况。每一种情况对应的判断条件都会有所不同,在这里就只和大家分享一下我对这个题的理解,不做详细的分析。
常见的链表面试题就这么多了,其实现在回头看这些题,解题的思路都略相像。可能不同的是,每个题想要的考察侧重点,学会分析题目的思路很重要,对题设要求一定要尽可能考虑到所有的情况。
- 链表面试题总结(二)
- 链表面试题(二)
- 链表面试题总结(一)
- 链表面试题总结(一)
- 链表面试题代码总结(java)
- 链表面试题 进阶 二
- 单链表面试题总结
- 常见链表面试题总结
- 链表面试题 解法总结
- 链表面试题(一)
- 链表面试题(一)
- 链表面试笔试题目总结
- 常见链表面试题的总结
- 热门题---链表面试题总结
- 链表面试笔试题目总结
- 链表面试题总结 C/C++
- 链表面试题小结(待完成)
- 单链表面试题汇总(1)
- 有关MySql编写可重复执行的sql(主要用于部署升级等)
- 设计模式-行为设计模式:责任链模式 ResponsibilityChain
- SynchronousQueue,LinkedBlockingQueue,ArrayBlockingQueue
- Andorid SDK Manager详解
- 关于DBCP及使用。纯JDBC架构。
- 链表面试题总结(二)
- SQLite3 C语言API入门
- 串口设置
- 浅谈新能源与计算机
- 软件英文术语缩写大全
- [LeetCode]64. Minimum Path Sum
- 【PHP】获取变量的类型
- git中设置http代理和取消http代理
- CSS的选择器