leetcode热题100刷题计划

二叉树的最近公共祖先

题目

思路

哈哈,做不出来。
思路来自大佬

终止条件

  1. 如果root为空,则直接返回
  2. 如果p,q指向同一结点,直接返回p
  3. 如果p,q任意一个和root相同,直接返回根

递归

去根节点左侧递归,返回值为left;去根节点右侧递归,返回值为right

返回值

  1. 如果都为空,则证明没有公共祖先,返回null
  2. 如果左侧为空,则返回右侧right;证明p,q全在右侧子树上
  3. 如果右侧为空,则返回左侧left,证明全在左侧子树上
  4. 左右都不为空,则公共祖先结点必然是root

代码


class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(null==root||p==root||q==root){
            return root;
        }
        if(p==q){
            return p;
        }
        
        TreeNode left=lowestCommonAncestor(root.left,p,q);
        TreeNode right=lowestCommonAncestor(root.right,p,q);
        if(left==null&&right==null){
            return null;
        }
        if(left==null) return right;
        if(right==null) return left;
        return root;
    }
}


二叉树中的最大路径和

题目

思路

一眼看过去,可以用把所有路径都遍历了,然后把遍历结果塞到一个数组里进行比较。但是路径太多了,这个方法行不通。没其他思路了,那就递归,每个结点可以存到叶结点的路径和。

代码



class Solution {

    int maxsum=Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
        maxpath(root);
        return maxsum;
    }

    public int maxpath(TreeNode root){
        if(null==root){
            return 0;
        }

        //去两侧找最大
        int leftsum=Math.max(maxpath(root.left),0);
        int rightsum=Math.max(maxpath(root.right),0);
		
		//加上自己本身后的值
        int now=root.val+leftsum+rightsum;

        maxsum=Math.max(maxsum,now);
        //返回最大值
        return root.val+Math.max(leftsum,rightsum);
    }
}

前k个高频元素

题目

思路

前k个肯定要用到大根堆。用哈希表存储值和对应次数,然后对次数进行堆排序,循环k次。

代码

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map occurrences = new HashMap();
        for (int num : nums) {
            occurrences.put(num, occurrences.getOrDefault(num, 0) + 1);
        }

        // int[] 的第一个元素代表数组的值,第二个元素代表了该值出现的次数
        //大根堆
        PriorityQueue queue = new PriorityQueue(new Comparator() {
            public int compare(int[] m, int[] n) {
                return m[1] - n[1];
            }
        });



        //二话不说先把堆填到k个,然后新的和堆中的比较,等到结束后,留下的就是最多的k个
        for (Map.Entry entry : occurrences.entrySet()) {
            int num = entry.getKey(), count = entry.getValue();
            if (queue.size() == k) {
                //队列头是队列中频次最小的一组;如果当前频次比队列头大,则直接队列头的位置
                if (queue.peek()[1] < count) {
                    queue.poll();
                    queue.offer(new int[]{num, count});
                }
            } else {
                queue.offer(new int[]{num, count});
            }
        }
        int[] ret = new int[k];
        for (int i = 0; i < k; ++i) {
            ret[i] = queue.poll()[0];
        }
        return ret;
    }
}



注意

官方题解说是优先队列是小根堆,实际上是错误的。优先队列本质就是大根堆,只不过用的时候,把大根堆其中最小的一个扔出去了。

你可能感兴趣的:(leetcode,学习,算法)