转自:https://blog.csdn.net/Together_CZ/article/details/74906427
1.面试7:使用两个栈实现一个队列。
//猛一看有点晕,实际上很简单。
使用两个栈,一个是保存输入S1,另一个是输出S2;
当有新元素插入到队尾时,就将元素放入S1中;
当要删除队头元素的时候,若S2不为空,那么就弹S2的首元素;否则将S1中全部出栈压入S2中,再弹出,如果S1为空,那么就没有元素了。
2.面试 13:在O(1)时间内删除链表节点
那么就找到一个结点指针的下一个节点,并将元素赋值,并且删除下一个节点,并将指针指向下下一个节点。
如果是删除最后一个节点,那么就需要遍历了。
3.面试26:复制复杂链表
节点结构定义:
public static class ComplexListNode {
int value;
ComplexListNode next;//指向下一个节点
ComplexListNode sibling;//有一个指向任意节点的指针。
}
//如果是使用普通复制的话,那么需要两个遍历的指针,并且时间复杂度是O(n^2)。
假设原始状态是这样的:
第一步:在每一个节点后面加上一个复制的节点;第二步,每一个复制节点的sibling指针,就指向签一个节点的sibling节点的下一个节点,第三步,奇偶拆分。
这个并不需要赋存,而且复杂度是O(n)的!!!
4.面试题27:二叉搜索树与双向链表
题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
//猛一看都懵了啊!完全不会啊!
因为二叉树中的节点包括指向左子树和右子树的指针,而且双向链表中有指向前一个节点和后一个节点的指针,那么是可以实现转化的。
只要将当前根节点的左指针指向,左子树中最大的节点;右指针指向右子树中最小的节点即可。
那么递归地去进行,先将左子树转化为双链表,将根节点地左子节点指针指向最后一个节点;然后去处理右子树,将根的右子节点指向右子树的第一个节点。
5.面试30:最小的K个数
O(nlogk)的复杂度,使用最大堆来实现;
最大堆最多存储K个数,如果当前堆未满,那么就直接放进来,如果已经满了,那么就和堆定元素比较,如果比堆定元素小,那么就将堆顶元素替换,再调整堆;
如果比堆定元素大,那么肯定就不在这K个数中,其实可以用优先队列来实现啊。
6.面试题56:链表中环的入口结点
一个链表中包含环,如何找出环的入口结点?
//猛一看是不会的。
使用两个指针,那么P1和P2,先让P1走环中节点的长度n,然后两个指针以相同速度向前移动,第二个指针指向环入口的节点,那么第一个指针也已经到了环入口节点,二者相等。
那么如何求环中有多少个指针呢?使用快慢指针,如果两个指针相遇,那么表明链表中存在环,从相遇的节点出发,遍历一周边计数,当再次回到这个节点就可以得出环中节点个数了。