二叉树
二叉树的最近公共祖先
递归:
public class LowestCommonAncestor {
private TreeNode answer;
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
ifHavePorQ(root, p, q);
return answer;
}
// 这道题的难点在于 你不要去想公共父结点的递归,你要去想左右子树里有没有p或者q,如果左右子树都有p或q
// 那么公共父结点就是root(我称之为异构的情况),或者另外一个场景,p或q本身就是另一个的公共父结点,(我称之为同构)
public boolean ifHavePorQ(TreeNode root, TreeNode p, TreeNode q) {
if(root==null) {
return false;
}
boolean ifLeftHasPorQ = ifHavePorQ(root.left, p,q);
boolean ifRightHasPorQ = ifHavePorQ(root.right,p,q);
if((ifLeftHasPorQ&&ifRightHasPorQ) || (( root.val==p.val || root.val==q.val)&&(ifLeftHasPorQ||ifRightHasPorQ)))
{
answer = root;
}
// 这就是左右子树里有没有p或者q的条件
return ifLeftHasPorQ || ifRightHasPorQ || root.val==p.val || root.val==q.val;
}
}
非递归:
方法二:存储父节点
思路
我们可以用哈希表存储所有节点的父节点,然后我们就可以利用节点的父节点信息从 p 结点开始不断往上跳,并记录已经访问过的节点,再从 q 节点开始不断往上跳,如果碰到已经访问过的节点,那么这个节点就是我们要找的最近公共祖先。
算法
从根节点开始遍历整棵二叉树,用哈希表记录每个节点的父节点指针。
从 p 节点开始不断往它的祖先移动,并用数据结构记录已经访问过的祖先节点。
同样,我们再从 q 节点开始不断往它的祖先移动,如果有祖先已经被访问过,即意味着这是 p 和 q 的深度最深的公共祖先,即 LCA 节点。
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
HashMap<TreeNode, TreeNode> myHashMap = new HashMap<>();
preOrder(root, myHashMap);
Set<TreeNode> fathersOfP = new HashSet();
TreeNode cur = p;
while(cur!=null) {
fathersOfP.add(cur);
cur=myHashMap.get(cur);
}
cur=q;
while(cur!=null) {
if(fathersOfP.contains(cur)) {
return cur;
}
cur=myHashMap.get(cur);
}
return null;
}
public void preOrder(TreeNode root, HashMap<TreeNode, TreeNode> myHashMap) {
if(root==null) {
return;
}
if(root.left!=null) {
myHashMap.put(root.left, root);
preOrder(root.left, myHashMap);
}
if(root.right!=null) {
myHashMap.put(root.right, root);
preOrder(root.right, myHashMap);
}
}
}
LRU
LRU可以使用LinkedHashMap实现
accessOrder是true就是按照get的顺序调整,最近访问过的放到链表尾部
false就是按照插入顺序
afterNodeAccess 就是在node被访问过后,调整它到链表尾部,这个方法在hashmap的get put等都会调用
afterNodeInsertion 默认是不删除结点,可以override这个里面的
removeEldestEntry函数
这样就可以在size>容量的时候,把头结点,最不常用的删除
可以参考博客(就参考这个博客就足够了)
超详细LinkedHashMap解析_求offer的菜鸡的博客-CSDN博客_linkedhashmap
public class LinkedHashMapCache extends LinkedHashMap {
private int capacity;
public LinkedHashMapCache(int capacity) {
// accsessOrder为true
super(capacity, 0.75F, true);
this.capacity = capacity;
}
public int get(int key) {
return (int)super.getOrDefault(key, -1);
}
public void put(int key, int value) {
super.put(key,value);
}
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > capacity;
}
}