刷题笔记23——二叉搜索树+快排+最近公共祖先

不必说碧绿的菜畦,光滑的石井栏,高大的皂荚树,紫红的桑椹;也不必说鸣蝉在树叶里长吟,肥胖的黄蜂伏在菜花上,轻捷的叫天子(云雀)忽然从草间直窜向云霄里去了。单是周围的短短的泥墙根一带,就有无限趣味。油蛉在这里低唱,蟋蟀们在这里弹琴。翻开断砖来,有时会遇见蜈蚣;还有斑蝥,倘若用手指按住它的脊梁,便会拍的一声,从后窍喷出一阵烟雾。何首乌藤和木莲藤缠络着,木莲有莲房一般的果实,何首乌有拥肿的根。有人说,何首乌根是有象人形的,吃了便可以成仙,我于是常常拔它起来,牵连不断地拔起来,也曾因此弄坏了泥墙,却从来没有见过有一块根象人样。如果不怕刺,还可以摘到覆盆子,象小珊瑚珠攒成的小球,又酸又甜,色味都比桑椹要好得远。

98. 验证二叉搜索树(按照遍历的方式所有的节点都会遇到一遍,要想清楚每遇到一个节点,这个节点需要干什么)

class Solution {
    long cur = Long.MAX_VALUE;
    public boolean isValidBST(TreeNode root) {
        if(root==null) return true;
        boolean a = isValidBST(root.right);
        boolean x = root.val<cur?true:false;
        cur = (long)root.val;
        boolean b = isValidBST(root.left);
        return a&x&b;
    }
}

700. 二叉搜索树中的搜索

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root == null) return null;
        if(root.val == val) return root;
        else if(root.val>val) return searchBST(root.left,val);
        else return searchBST(root.right,val);
    }
}

96. 不同的二叉搜索树

class Solution {
    public int numTrees(int n) {
        if(n==0 || n==1) return 1;
        int sum = 0;
        for(int i=1;i<=n;i++){
            sum = sum + numTrees(i-1)*numTrees(n-i);
        }
        return sum;
    }
}

95. 不同的二叉搜索树 II(区别就是需要把这棵树构造出来)

class Solution {
    public List<TreeNode> generateTrees(int n) {
        List<TreeNode> ans = new ArrayList<TreeNode>();
        if(n==0) return null;
        return generateTree(1,n);
    }

    List<TreeNode> generateTree(int left,int right){
        List<TreeNode> temp = new ArrayList<TreeNode>();
        if(right<left){
            temp.add(null);
            return temp;
        }

        if(left==right){
            TreeNode re = new TreeNode(left);
            temp.add(re);
            return temp;
        } 
        
        for(int i=left;i<=right;i++){
            List<TreeNode> leftTrees = generateTree(left,i-1);
            List<TreeNode> rightTrees = generateTree(i+1,right);
            for(TreeNode leftTree : leftTrees){
                for(TreeNode rightTree : rightTrees){
                    TreeNode root = new TreeNode(i);
                    root.left = leftTree;
                    root.right = rightTree;
                    temp.add(root);
                }
            }
        }
        return temp;
    }
}


归并是先把小部分排列好,然后进行合并,类似于后序遍历

快排是先定好一个的位置,然后对左右进行排列,类似于前序遍历

215. 数组中的第K个最大元素

  • 最开始一直被难到的地方就是进入while之后,怎么左右切换着遍历,现在用的思路就是,先把空元素换到右边,再换到左边,就和一开始情况一模一样了,但是要注意,一定要nums[left] = temp;找到对应位置后,这个位置是空的值(乱值),要用正确的temp更换后再返回!!!
class Solution {
    public int findKthLargest(int[] nums, int k) {
        int len = nums.length;
        int result = quickSort(nums,0,len-1,k-1);
        return result;
    }

    public int quickSort(int[] nums, int l, int r,int k){
        int temp = nums[l];
        int left = l;
        int right = r;

        while(left!=right){
            // 两边都走但是用temp进行限制,但是这样不会排除重复元素
            while(nums[right]<=temp && left<right) right--;
            nums[left] = nums[right];

            while(nums[left]>=temp && left<right) left++;
            nums[right] = nums[left];
        }

        nums[left] = temp;
        if(left==k) return nums[k];
        else if(left<k) return quickSort(nums,left+1,r,k);
        else return quickSort(nums,l,right-1,k);
    }
}

236. 二叉树的最近公共祖先

  • return的一直是找到的节点,找到左就return左,找到右就return右;
  • 直到在某个root上两边都有return,就返回该节点一直向上
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null||root==p||root==q) return root;
        TreeNode left = lowestCommonAncestor(root.left,p,q);
        TreeNode right = lowestCommonAncestor(root.right,p,q);
        if(left!=null && right!=null) return root;
        else if(left!=null) return left;
        else if(right!=null) return right;
        else return null;
    }
}

235. 二叉搜索树的最近公共祖先

  • 二叉搜索树在找某个节点时相比于一般的二叉树具有非常大的优势
  • 一般遇到的具体到几个节点上的情况,都可以通过while遍历寻找
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        List<TreeNode> path_p = getPath(root,p);
        List<TreeNode> path_q = getPath(root,q);
        TreeNode res = new TreeNode();
        for(int i=0;i< path_p.size()&& i<path_q.size();i++){
            if(path_p.get(i) == path_q.get(i)){
                res = path_p.get(i);
            }else{
                break;
            }
        }
        return res;
    }

    public List<TreeNode> getPath(TreeNode root,TreeNode target){
        List<TreeNode> res = new LinkedList<TreeNode>();
        res.add(root);
        if(root==target) return res;

        while(root!=target){
            if(root.val>target.val){
                root = root.left;
            }else{
                root = root.right;
            }
            res.add(root);
        }
        return res;
    }
}

你可能感兴趣的:(笔记,数据结构,leetcode)