经典算法面试题

1、如何判断链表中是否有环?如果有环的话,如何找出环的入口

设置两个指针,一个fast指针,一个slow指针,fast指针每次走两步,slow指针每次走一步,若fast和slow相遇,则链表有环

设x为slow走的步数,则2x = x + n,n为环的大小,则相遇时,slow走了n步

则表头到环入口的距离 = 相遇点到环入口的距离

于是在相遇点,将fast指针移动到表头,每次走一步,和slow指针的相遇点就是环的入口

具体可以见我的另一篇博客:剑指Offer-链表中环的入口节点

2、如何找出二叉树中两个节点最低的公共父节点

1)这个二叉树是二叉排序树

从根节点开始遍历:

若两个节点的值都小于当前节点,则继续遍历左子树;

若两个节点的值都大于当前节点,则继续遍历右子树;

若一个节点的值大于当前节点,一个节点的值小于当前节点,则返回当前节点

2)普通二叉树,存在指向父节点的指针

给定任意节点,可以找到从该节点到根节点的路径

则问题转化为两个单向链表的第一个公共父节点

A、求出两个链表的长度,两个指针指向这两个链表的头节点,长链表的指针先移动K步(两个链表的长度差),然后同时开始移动,返回第一个相同的节点

B、设置两个栈,两个链表的节点分别入栈(从节点到根节点的路径),同时弹出一个节点,直到最后一对相同的节点,即为两个链表的第一个公共父节点

3)普通二叉树,不存在指向父节点的指针

A、判断某子树中是否有某个节点

若两个节点都在右子树,则递归在右子树中寻找;

若都在左子树,则递归在左子树中寻找;

若一个在左子树,一个在右子树,返回当前节点;

B、寻找从根节点到子节点的路径

用栈遍历二叉树,最后找到从根节点到子节点的路径 (右节点,左节点先后入栈)

C、递归遍历

根root,两个节点p,q,前序遍历,若只找到p则返回p,若只找到q则返回q,如果某个节点左右分别找到p,q,则返回该节点

3、两个栈实现一个队列

A、【思路一】

stack1作为存储区,stack2作为临时缓冲区

入队的时候,元素直接压入stack1;

出队的时候,stack1的元素倒入stack2,将stack2的栈顶元素出队,然后将剩余元素倒回stack1

入队时间复杂度O(1),出队时间复杂度O(2n)

B、【思路二】

入队的时候,如果stack1为空,把stack2中所有的元素倒出压到stack1中,再将元素直接压入stack1。否则直接压入stack1   

出队列时候,如果stack2不为空,把stack2中的栈顶元素直接弹出。否则,把stack1的所有元素全部弹出压入stack2中,再弹出stack2的栈顶元素

C、【思路三】

设定stack1是入栈的,stack2是出栈的

入队的时候,直接压入元素至stack1即可

出队的时候,判断stack2是否为空,如果stack2为空,则将stack1中的元素倒入stack2中,否则直接弹出stack2中的元素

4、最长公共子序列、最长公共子串的问题

未完待续.......

猜你喜欢

转载自blog.csdn.net/ljh0302/article/details/81130429