常用于面试的链表操作算法
2011-11-30 00:00
711 查看
链表操作在面试中会经常出现,下面列举的链表操作方法是比较典型的。
问题1:输入一个单向链表,输出该链表中倒数第k个结点
一个单向链表无法像数组一样可以直接索引,那么要找到链表的倒数第K个节点该怎么操作呢,其实思路非常简单,我们只需要设置两个指针p1,p2,首先p1和p2都指向链表的头部head,然后p2向前走k步,这样p1和p2之间就间隔k个节点,最后p1和p2同时向前移动,直至p2走到链表末尾,然后返回p1就是我们要找的链表的倒数K个节点。
问题2:如何判断一个链表有环
这个问题可以这么来分析我们可以设置两个指针(p1, p2),初始值都指向头,p1每次前进一步,p2每次前进二步,如果链表存在环,则p2先进入环,p1后进入环,两个指针在环中走动,必定相遇,如何两节点相遇说明了这个链表存在一个环,以此思路给出了一下代码片段:
问题3:如何判断两个链表是否相交
分析:问题可以分为两种情况,第一种情况如果两个链表都没有环的话,那么两个链表要是相交,那么从他们相交的那一点开始到尾节点两个链表应该完全相同,这样我们就可以直接判断链表的尾节点是否相同来进行判断两链表是否相交来进行判断。第二种情况的话如果两个链表存在环的话,那么我们则应该判断一链表上俩指针相遇的那个节点,在不在另一条链表上,如果在,则相交,如果不在,则不相交。由此可给出下面的代码片段:
大概就这样,希望对你面试有用。
问题1:输入一个单向链表,输出该链表中倒数第k个结点
一个单向链表无法像数组一样可以直接索引,那么要找到链表的倒数第K个节点该怎么操作呢,其实思路非常简单,我们只需要设置两个指针p1,p2,首先p1和p2都指向链表的头部head,然后p2向前走k步,这样p1和p2之间就间隔k个节点,最后p1和p2同时向前移动,直至p2走到链表末尾,然后返回p1就是我们要找的链表的倒数K个节点。
struct ListNode{ char data; ListNode *next; }; ListNode *head, *p1, *p2; ListNode *func(ListNode *head, int k){ assert(k>=0); //保证k应该要大于0 p1 = p2 = head; for (; k>0; k--) p2 = p2->next; //移动p2到与p1距离k个位置 if (k>0) return //要考虑到链表的元素可以小于k个 while(p2!=NULL){ p2 = p2->next; p1 = p1->next; //移动p1,p2直到p2到达最后 } return p1; }
问题2:如何判断一个链表有环
这个问题可以这么来分析我们可以设置两个指针(p1, p2),初始值都指向头,p1每次前进一步,p2每次前进二步,如果链表存在环,则p2先进入环,p1后进入环,两个指针在环中走动,必定相遇,如何两节点相遇说明了这个链表存在一个环,以此思路给出了一下代码片段:
struct Node{ int data; Node *next; } bool isCircle(Node *head, Node *CircleNode, Node *lastNode){ Node *fast = head->next; //步长为2的节点 Node *slow = head; //步长为1的节点 while(fast != slow && fast && slow){ //当两节点不相遇且还未到达末尾时进行循环 if (fast->next != NULL) fast = fast->next; if (fast->next ==NULL) lastNode = fast; //记录尾节点 if (slow->next = NULL) lastNode = slow; //记录尾节点 fast = fast->next; slow= slow->next; } if (fast == slow && fast && slow){ CircleNode = fast; //记录相遇的节点 return True; } else return false; }
问题3:如何判断两个链表是否相交
分析:问题可以分为两种情况,第一种情况如果两个链表都没有环的话,那么两个链表要是相交,那么从他们相交的那一点开始到尾节点两个链表应该完全相同,这样我们就可以直接判断链表的尾节点是否相同来进行判断两链表是否相交来进行判断。第二种情况的话如果两个链表存在环的话,那么我们则应该判断一链表上俩指针相遇的那个节点,在不在另一条链表上,如果在,则相交,如果不在,则不相交。由此可给出下面的代码片段:
bool detect(Node *head1, Node *head2){ Node *circleNode1; //链表1的相交节点 Node *circleNode2; //链表2的相交节点 Node *lastNode1; //链表1的尾节点 Node *lastNode2; //链表2的尾节点 bool isCircle1 = isCircle(head1, circleNode1, lastNode1); //判断链表1是否存在环 bool isCircle2 = isCircle(head2, circleNode2, lastNode2); //判断链表2是否存在环 if (isCircle1 != isCircle2) return false; else if (!isCircle1 && !isCircle2){ //如果两链表都不存在环可以直接对尾节点进行比较看是否相交 return lastNode1 == lastNode2; } else{ //如果连链表都存在环的话要看相交节点是不是在两链表都出现 Node *temp = circleNode1->next; while(temp != circleNode1){ if (temp == circleNode2) return true; temp = temp->next; } return false; } return false; }
大概就这样,希望对你面试有用。
相关文章推荐
- C/C++面试之算法系列--典型的几个链表操作-逆序和重排
- 面试算法之链表操作集锦
- 面试算法之链表操作集锦
- 面试算法之链表操作集锦
- C/C++面试之算法系列--一次遍历找链表倒数第n个节点
- 单链表的算法操作
- 微软等数据结构+算法面试100题(43)-- 把二元查找树转变成排序的双向链表
- 【LeetCode-面试算法经典-Java实现】【225-Implement Stack using Queues(用队列实现栈操作)】
- leetcode:Reverse Nodes in k-Group(以k为循环节反转链表)【面试算法题】
- 面试 7:快慢指针法玩转链表算法面试(一)
- 那些年我们面试过的单链表算法总结(二)
- 转:C/C++面试之算法系列--怎样快速检测出一个巨大的单链表中是否具备死链及其位置
- JAVA中关于链表的操作和基本算法
- 【数据结构和算法分析】双链表的增,删操作
- 数据结构 - 链表 - 面试中常见的链表算法题
- 链表操作算法题合集
- 面试算法:利用链表层级打印二叉树节点
- 1326 Problem A 算法2-8~2-11:链表的基本操作
- 它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, Adi Shamir 和Leonard Adleman。但RSA的安全性一直未能得到理论上的证明。它经历了各种攻击,至今未被
- JAVA中关于链表的操作和基本算法