Leetcode_入门_BST

BST

1、修剪二叉搜索树(669、Easy)

1)题目要求

给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。

示例 1:

输入:
1
/
0 2

L = 1
R = 2

输出:
1

2
示例 2:

输入:
3
/
0 4

2
/
1

L = 1
R = 3

输出:
3
/
2
/
1

2)我的解法

class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
        if(root==null)return null;
        if(root.val<=high&&root.val>=low){
            root.left=trimBST(root.left,low,root.val);
            root.right=trimBST(root.right,root.val,high);
        }
        else if(root.val<low)root=trimBST(root.right,low,high);
        else root=trimBST(root.left,low,high);
        return root;
    }
}

3)其他解法

class Solution {
    public TreeNode trimBST(TreeNode root, int L, int R) {
        if (root == null) return root;
        if (root.val > R) return trimBST(root.left, L, R);
        if (root.val < L) return trimBST(root.right, L, R);

        root.left = trimBST(root.left, L, R);
        root.right = trimBST(root.right, L, R);
        return root;
    }
}

作者:LeetCode
链接:link
来源:力扣(LeetCode)

4)自己的优化代码

class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
        if(root==null)return null;
        if(root.val<low)return trimBST(root.right,low,high);
        if(root.val>high) return trimBST(root.left,low,high);
        root.left=trimBST(root.left,low,high);
        root.right=trimBST(root.right,low,high);
        return root;
    }
}

5)学到的东西

递归思想

2、二叉搜索树中第K小的元素(230、Medium)

1)题目要求

给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。

说明:
你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。

示例 1:

输入: root = [3,1,4,null,2], k = 1
3
/
1 4

2
输出: 1
示例 2:

输入: root = [5,3,6,2,4,null,null,1], k = 3
5
/
3 6
/
2 4
/
1
输出: 3
进阶:
如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化 kthSmallest 函数?

2)我的解法

class Solution {
    private List<Integer> result=new ArrayList<>();
    public void getResult(TreeNode root){
        if(root==null)return ;
        getResult(root.left);
        result.add(root.val);
        getResult(root.right);
    }
    public int kthSmallest(TreeNode root, int k) {
        getResult(root);
        return result.get(k-1);
    }
}

3)其他解法

1、递归

class Solution {
  public ArrayList<Integer> inorder(TreeNode root, ArrayList<Integer> arr) {
    if (root == null) return arr;
    inorder(root.left, arr);
    arr.add(root.val);
    inorder(root.right, arr);
    return arr;
  }

  public int kthSmallest(TreeNode root, int k) {
    ArrayList<Integer> nums = inorder(root, new ArrayList<Integer>());
    return nums.get(k - 1);
  }
}


2、迭代

class Solution {
  public int kthSmallest(TreeNode root, int k) {
    LinkedList<TreeNode> stack = new LinkedList<TreeNode>();

    while (true) {
      while (root != null) {
        stack.add(root);
        root = root.left;
      }
      root = stack.removeLast();
      if (--k == 0) return root.val;
      root = root.right;
    }
  }
}

作者:LeetCode
链接:link
来源:力扣(LeetCode)

4)自己的优化代码

class Solution {
    private List<Integer> result=new ArrayList<>();
    public void getResult(TreeNode root){
        if(root==null)return ;
        getResult(root.left);
        result.add(root.val);
        getResult(root.right);
    }
    public int kthSmallest(TreeNode root, int k) {
        getResult(root);
        return result.get(k-1);
    }
}

5)学到的东西

二叉搜索树中序遍历结果为有序

3、把二叉搜索树转换为累加树(538、Easy)

1)题目要求

给定一个二叉搜索树(Binary Search Tree),把它转换成为累加树(Greater Tree),使得每个节点的值是原来的节点值加上所有大于它的节点值之和。

例如:

输入: 原始二叉搜索树:
5
/
2 13

输出: 转换为累加树:
18
/
20 13

2)我的解法

class Solution {
    List<Integer> list=new ArrayList<>(); 
    public TreeNode convertBST(TreeNode root) {
        if(root==null)return null;
        convertBST(root.right);
        int temp=root.val;
        list.add(root.val);
        for(Integer i:list){
            if(i>temp)root.val+=i;
        }
        convertBST(root.left);
        return root;
    }
}

优化:

class Solution {
    private int sum=0;
    public TreeNode convertBST(TreeNode root) {
        if(root==null)return null;
        convertBST(root.right);
        int temp=root.val;
        root.val+=sum;
        sum+=temp;
        convertBST(root.left);
        return root;
    }
}

3)其他解法

在这里插入图片描述

class Solution {
    private int sum = 0;

    public TreeNode convertBST(TreeNode root) {
        if (root != null) {
            convertBST(root.right);
            sum += root.val;
            root.val = sum;
            convertBST(root.left);
        }
        return root;
    }
}

在这里插入图片描述

class Solution {
    public TreeNode convertBST(TreeNode root) {
        int sum = 0;
        TreeNode node = root;
        Stack<TreeNode> stack = new Stack<TreeNode>();

        while (!stack.isEmpty() || node != null) {
            /* push all nodes up to (and including) this subtree's maximum on
             * the stack. */
            while (node != null) {
                stack.add(node);
                node = node.right;
            }

            node = stack.pop();
            sum += node.val;
            node.val = sum;

            /* all nodes with values between the current and its parent lie in
             * the left subtree. */
            node = node.left;
        }

        return root;
    }
}

4)自己的优化代码

class Solution {
    private int sum=0;
    public TreeNode convertBST(TreeNode root) {
        if(root==null)return null;
        convertBST(root.right);
        root.val+=sum;
        sum=root.val;
        convertBST(root.left);
        return root;
    }
}

5)学到的东西

二叉搜索树中序即为有序

4、 二叉搜索树的最近公共祖先(235、Easy)

1)题目要求

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]

示例 1:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。
示例 2:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

说明:

所有节点的值都是唯一的。
p、q 为不同节点且均存在于给定的二叉搜索树中。

2)我的解法


class Solution {

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null)return null;
        if(root.val>Math.max(q.val,p.val))return lowestCommonAncestor(root.left,p,q);
        if(root.val<Math.min(q.val,p.val))return lowestCommonAncestor(root.right,p,q);
        return root;
    }
}

3)其他解法

1、递归

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {

        // Value of current node or parent node.
        int parentVal = root.val;

        // Value of p
        int pVal = p.val;

        // Value of q;
        int qVal = q.val;

        if (pVal > parentVal && qVal > parentVal) {
            // If both p and q are greater than parent
            return lowestCommonAncestor(root.right, p, q);
        } else if (pVal < parentVal && qVal < parentVal) {
            // If both p and q are lesser than parent
            return lowestCommonAncestor(root.left, p, q);
        } else {
            // We have found the split point, i.e. the LCA node.
            return root;
        }
    }
}

2、迭代

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {

        // Value of p
        int pVal = p.val;

        // Value of q;
        int qVal = q.val;

        // Start from the root node of the tree
        TreeNode node = root;

        // Traverse the tree
        while (node != null) {

            // Value of ancestor/parent node.
            int parentVal = node.val;

            if (pVal > parentVal && qVal > parentVal) {
                // If both p and q are greater than parent
                node = node.right;
            } else if (pVal < parentVal && qVal < parentVal) {
                // If both p and q are lesser than parent
                node = node.left;
            } else {
                // We have found the split point, i.e. the LCA node.
                return node;
            }
        }
        return null;
    }
}

作者:LeetCode
链接: link
来源:力扣(LeetCode)

4)自己的优化代码

class Solution {

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null)return null;
        if(root.val>Math.max(q.val,p.val))return lowestCommonAncestor(root.left,p,q);
        if(root.val<Math.min(q.val,p.val))return lowestCommonAncestor(root.right,p,q);
        return root;
    }
}

5)学到的东西

二叉搜索树(BST)的性质:

1、节点 NN 左子树上的所有节点的值都小于等于节点 NN 的值
2、节点 NN 右子树上的所有节点的值都大于等于节点 NN 的值
3、左子树和右子树也都是 BST

递归思想、迭代思想

5、二叉树的最近公共祖先(236、Medium)

1)题目要求

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]

在这里插入图片描述

示例 1:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和节点 1 的最近公共祖先是节点 3。
示例 2:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出: 5
解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。

说明:

所有节点的值都是唯一的。
p、q 为不同节点且均存在于给定的二叉树中。

2)我的解法

class Solution {
    public boolean findTree(TreeNode root ,TreeNode target){
        if(root==null)return false;
        if(root.val==target.val)return true;
        return findTree(root.left,target)||findTree(root.right,target);
    }
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null)return null;
        if(root.val==p.val&&(findTree(root.left,q)||findTree(root.right,q)))return root;
        if(root.val==q.val&&(findTree(root.left,p)||findTree(root.right,p)))return root;
        if((findTree(root.left,p)||findTree(root.left,q))
        &&(findTree(root.right,p)||findTree(root.right,q)))return root;
        if(findTree(root.left,p)||findTree(root.left,q))return lowestCommonAncestor(root.left,p,q);
        if(findTree(root.right,p)||findTree(root.right,q))return lowestCommonAncestor(root.right,p,q);
        return null;
    }
}

3)其他解法

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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) return right;
        if(right == null) return left;
        return root;
    }
}

展开:

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 null; // 1.
        if(left == null) return right; // 3.
        if(right == null) return left; // 4.
        return root; // 2. if(left != null and right != null)
    }
}


作者:jyd
链接:link
来源:力扣(LeetCode)

4)自己的优化代码

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

5)学到的东西

递归思想,这种判断没必要单独弄一个判断函数,只需根据不同情况在递归时返回不同值即可

分类讨论

递归解析:1终止条件 2递归操作 3返回值

6、 将有序数组转换为二叉搜索树(108、Easy)

1)题目要求

将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

示例:

给定有序数组: [-10,-3,0,5,9],

一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:

  0
 / \

-3 9
/ /
-10 5

2)我的解法

class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        if(nums.length==0)return null;
        if(nums.length==1)return new TreeNode(nums[0]);
        TreeNode root=new TreeNode(nums[nums.length/2]);
        int[] l=new int[nums.length/2];
        int[] r=new int[nums.length-nums.length/2-1];
        System.arraycopy(nums,0,l,0,nums.length/2);
        System.arraycopy(nums,nums.length/2+1,r,0,nums.length-nums.length/2-1);
        root.left=sortedArrayToBST(l);
        root.right=sortedArrayToBST(r);
        return root;
    }
}

3)其他解法

1、

class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        return helper(nums, 0, nums.length - 1);
    }

    public TreeNode helper(int[] nums, int left, int right) {
        if (left > right) {
            return null;
        }

        // 总是选择中间位置左边的数字作为根节点
        int mid = (left + right) / 2;

        TreeNode root = new TreeNode(nums[mid]);
        root.left = helper(nums, left, mid - 1);
        root.right = helper(nums, mid + 1, right);
        return root;
    }
}

2、

class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        return helper(nums, 0, nums.length - 1);
    }

    public TreeNode helper(int[] nums, int left, int right) {
        if (left > right) {
            return null;
        }

        // 总是选择中间位置右边的数字作为根节点
        int mid = (left + right + 1) / 2;

        TreeNode root = new TreeNode(nums[mid]);
        root.left = helper(nums, left, mid - 1);
        root.right = helper(nums, mid + 1, right);
        return root;
    }
}


3、

class Solution {
    Random rand = new Random();

    public TreeNode sortedArrayToBST(int[] nums) {
        return helper(nums, 0, nums.length - 1);
    }

    public TreeNode helper(int[] nums, int left, int right) {
        if (left > right) {
            return null;
        }

        // 选择任意一个中间位置数字作为根节点
        int mid = (left + right + rand.nextInt(2)) / 2;

        TreeNode root = new TreeNode(nums[mid]);
        root.left = helper(nums, left, mid - 1);
        root.right = helper(nums, mid + 1, right);
        return root;
    }
}

作者:LeetCode-Solution
链接:link_
来源:力扣(LeetCode)

4)自己的优化代码

class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        if(nums.length==0)return null;
        if(nums.length==1)return new TreeNode(nums[0]);
        TreeNode root=new TreeNode(nums[nums.length/2]);
        int[] l=new int[nums.length/2];
        int[] r=new int[nums.length-nums.length/2-1];
        System.arraycopy(nums,0,l,0,nums.length/2);
        System.arraycopy(nums,nums.length/2+1,r,0,nums.length-nums.length/2-1);
        root.left=sortedArrayToBST(l);
        root.right=sortedArrayToBST(r);
        return root;
    }
}

5)学到的东西

递归思想

7、有序链表转换二叉搜索树(109、Medium)

1)题目要求

给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

示例:

给定的有序链表: [-10, -3, 0, 5, 9],

一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:

  0
 / \

-3 9
/ /
-10 5

2)我的解法

class Solution {
    public TreeNode sortedListToBST(ListNode head) {
        if(head==null)return null;
        if(head.next==null)return new TreeNode(head.val);
        ListNode cur=head;
        int length=0;
        while(cur!=null){
            cur=cur.next;length++;
        }
        int i=0;
        cur=head;
        ListNode pre=head;
        while(i<length/2){
            pre=cur;
            cur=cur.next;
            i++;
        }
        TreeNode root=new TreeNode(cur.val);
        pre.next=null;
        root.left=sortedListToBST(head);
        root.right=sortedListToBST(cur.next);
        return root;
    }
}

3)其他解法

1、

在这里插入图片描述

class Solution {
    public TreeNode sortedListToBST(ListNode head) {
        return buildTree(head, null);
    }

    public TreeNode buildTree(ListNode left, ListNode right) {
        if (left == right) {
            return null;
        }
        ListNode mid = getMedian(left, right);
        TreeNode root = new TreeNode(mid.val);
        root.left = buildTree(left, mid);
        root.right = buildTree(mid.next, right);
        return root;
    }

    public ListNode getMedian(ListNode left, ListNode right) {
        ListNode fast = left;
        ListNode slow = left;
        while (fast != right && fast.next != right) {
            fast = fast.next;
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}

时间复杂度:nlogn,每次getMedian()都是o(1/2n)像这种一半的一半的一半。。。(包括二分查找也是这样)都是o(logn),而递归又进行了n次所以为o(nlogn)

2、

在这里插入图片描述

class Solution {
    ListNode globalHead;

    public TreeNode sortedListToBST(ListNode head) {
        globalHead = head;
        int length = getLength(head);
        return buildTree(0, length - 1);
    }

    public int getLength(ListNode head) {
        int ret = 0;
        while (head != null) {
            ++ret;
            head = head.next;
        }
        return ret;
    }

    public TreeNode buildTree(int left, int right) {
        if (left > right) {
            return null;
        }
        int mid = (left + right + 1) / 2;
        TreeNode root = new TreeNode();
        root.left = buildTree(left, mid - 1);
        root.val = globalHead.val;
        globalHead = globalHead.next;
        root.right = buildTree(mid + 1, right);
        return root;
    }
}


作者:LeetCode-Solution
链接:link
来源:力扣(LeetCode)

4)自己的优化代码

class Solution {
    ListNode Head=null;
    public TreeNode getResult(int l,int r){
        if(l>r)return null;
        int mid=(l+r+1)/2;//+1或不+都行,只是造出来的树不太一样而已
        TreeNode root=new TreeNode();
        root.left=getResult(l,mid-1);
        root.val=Head.val;
        Head=Head.next;
        root.right=getResult(mid+1,r);
        return root;
    }
    public TreeNode sortedListToBST(ListNode head) {
        if(head==null)return null;
        if(head.next==null)return new TreeNode(head.val);
        ListNode cur=head;
        Head=head;
        int length=0;
        while(cur!=null){
            cur=cur.next;length++;
        }
        return getResult(0,length-1);
    }
}

5)学到的东西

中序遍历+分治,可以避免每次都去找中间结点,降低时间复杂度

递归思想

8、两数之和 IV - 输入 BST(653、Easy)

1)题目要求

给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。

案例 1:

输入:
5
/
3 6
/ \
2 4 7

Target = 9

输出: True

案例 2:

输入:
5
/
3 6
/ \
2 4 7

Target = 28

输出: False

2)我的解法

class Solution {
    private Map<Integer,Integer> map=new HashMap<>();
    public boolean getResult(TreeNode root,int k){
        if(root==null)return false;
        boolean tag1=getResult(root.left,k);
        boolean tag2=false;
        if(map.containsKey(k-root.val))tag2=true;
        map.put(root.val,1);
        boolean tag3=getResult(root.right,k);
        return (tag1||tag2||tag3);
    }
    public boolean findTarget(TreeNode root, int k) {
        return getResult(root,k);
    }
}

3)其他解法

在这里插入图片描述

public class Solution {
    public boolean findTarget(TreeNode root, int k) {
        Set < Integer > set = new HashSet();
        return find(root, k, set);
    }
    public boolean find(TreeNode root, int k, Set < Integer > set) {
        if (root == null)
            return false;
        if (set.contains(k - root.val))
            return true;
        set.add(root.val);
        return find(root.left, k, set) || find(root.right, k, set);
    }
}

在这里插入图片描述

public class Solution {
    public boolean findTarget(TreeNode root, int k) {
        Set < Integer > set = new HashSet();
        Queue < TreeNode > queue = new LinkedList();
        queue.add(root);
        while (!queue.isEmpty()) {
            if (queue.peek() != null) {
                TreeNode node = queue.remove();
                if (set.contains(k - node.val))
                    return true;
                set.add(node.val);
                queue.add(node.right);
                queue.add(node.left);
            } else
                queue.remove();
        }
        return false;
    }
}


在这里插入图片描述

public class Solution {
    public boolean findTarget(TreeNode root, int k) {
        List < Integer > list = new ArrayList();
        inorder(root, list);
        int l = 0, r = list.size() - 1;
        while (l < r) {
            int sum = list.get(l) + list.get(r);
            if (sum == k)
                return true;
            if (sum < k)
                l++;
            else
                r--;
        }
        return false;
    }
    public void inorder(TreeNode root, List < Integer > list) {
        if (root == null)
            return;
        inorder(root.left, list);
        list.add(root.val);
        inorder(root.right, list);
    }
}

作者:LeetCode
链接: link
来源:力扣(LeetCode)

4)自己的优化代码

class Solution {
    private Set<Integer> set=new HashSet<>();
    public boolean getResult(TreeNode root,int k){
        if(root==null)return false;
        boolean tag1=getResult(root.left,k);
        if(set.contains(k-root.val))return true;
        set.add(root.val);
        boolean tag2=getResult(root.right,k);
        return (tag1||tag2);
    }
    public boolean findTarget(TreeNode root, int k) {
        return getResult(root,k);
    }
}

5)学到的东西

9、二叉搜索树的最小绝对差(530、Easy)

1)题目要求

给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。

示例:

输入:

1

3
/
2

输出:
1

解释:
最小绝对差为 1,其中 2 和 1 的差的绝对值为 1(或者 2 和 3)。

提示:

树中至少有 2 个节点。

2)我的解法

class Solution {
    private List<Integer> list=new ArrayList<>();
    int min=Integer.MAX_VALUE;
    public int getMinimumDifference(TreeNode root) {
        if(root==null)return 0;
        getMinimumDifference(root.left);
        if(list.size()>0)min=Math.min(min,Math.abs(root.val-list.get(list.size()-1)));
        list.add(root.val);
        getMinimumDifference(root.right);
        return min;
    }
}

3)其他解法

TreeNode pre = null;
int res = Integer.MAX_VALUE;

public int getMinimumDifference(TreeNode root) {
    if (root == null) return 0;
    helper(root);
    return res;
}

private void helper(TreeNode root) {
    if (root == null) return;
    helper(root.left);
    if (pre != null) {
        //求相邻节点的差值
        res = Math.min(res, Math.abs(root.val - pre.val));
    }
    pre = root;
    helper(root.right);
}

作者:mmmmmJCY
链接:link
来源:力扣(LeetCode)

4)自己的优化代码

class Solution {
    TreeNode pre=null;
    int min=Integer.MAX_VALUE;
    public int getMinimumDifference(TreeNode root) {
        if(root==null)return 0;
        getMinimumDifference(root.left);
        if(pre!=null)min=Math.min(min,Math.abs(root.val-pre.val));
        pre=root;
        getMinimumDifference(root.right);
        return min;
    }
}

5)学到的东西

仅与前一个有关,所以只需保存前一个即可,不需要用list

递归思想

10、二叉搜索树中的众数(501、Easy)

1)题目要求

给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。

假定 BST 有如下定义:

结点左子树中所含结点的值小于等于当前结点的值
结点右子树中所含结点的值大于等于当前结点的值
左子树和右子树都是二叉搜索树
例如:
给定 BST [1,null,2,2],

1

2
/
2
返回[2].

2)我的解法

class Solution {
    Map<Integer,Integer> map=new HashMap<>();
    List<Integer> list=new ArrayList<>();
    int max=0;
    public void getResult(TreeNode root){
        if(root==null)return;
        getResult(root.left);
        if(!map.containsKey(root.val))map.put(root.val,1);
        else map.put(root.val,map.get(root.val)+1);
        if(map.get(root.val)>max){
            max=map.get(root.val);
            list.clear();
            list.add(root.val);
        }
        else if(map.get(root.val)==max)list.add(root.val);
        getResult(root.right);
    }
    public int[] findMode(TreeNode root) {
        getResult(root);
        int[] result=new int[list.size()];
        for(int i=0;i<list.size();i++){
            result[i]=list.get(i);
        }
        return result;
    }
}

3)其他解法

思路:二叉搜索树的中序遍历是一个升序序列,逐个比对当前结点(root)值与前驱结点(pre)值。更新当前节点值出现次数(curTimes)及最大出现次数(maxTimes),更新规则:若curTimes=maxTimes,将root->val添加到结果向量(res)中;若curTimes>maxTimes,清空res,将root->val添加到res,并更新maxTimes为curTimes。

void inOrder(TreeNode* root, TreeNode*& pre, int& curTimes, 
             int& maxTimes, vector<int>& res){
    if (!root) return;
    inOrder(root->left, pre, curTimes, maxTimes, res);
    if (pre)
        curTimes = (root->val == pre->val) ? curTimes + 1 : 1;
    if (curTimes == maxTimes)
        res.push_back(root->val);
    else if (curTimes > maxTimes){
        res.clear();
        res.push_back(root->val);
        maxTimes = curTimes;
    }
    pre = root;
    inOrder(root->right, pre, curTimes, maxTimes, res);
}
vector<int> findMode(TreeNode* root) {
    vector<int> res;
    if (!root) return res;
    TreeNode* pre = NULL;
    int curTimes = 1, maxTimes = 0;
    inOrder(root, pre, curTimes, maxTimes, res);
    return res;
}

作者:junstat
链接:link
来源:力扣(LeetCode)

4)自己的优化代码

class Solution {

    List<Integer> list=new ArrayList<>();
    int max=0;
    TreeNode pre=new TreeNode(-9999);
    int cur=0;
    public void getResult(TreeNode root){
        if(root==null)return;
        getResult(root.left);
        cur=(list.size()>0&&root.val==pre.val)?cur+1:1;
        pre=root;
        if(cur>max){
            max=cur;
            list.clear();
            list.add(root.val);
        }
        else if(cur==max)list.add(root.val);
        getResult(root.right);
    }
    public int[] findMode(TreeNode root) {
        getResult(root);
        int[] result=new int[list.size()];
        for(int i=0;i<list.size();i++){
            result[i]=list.get(i);
        }
        return result;
    }
}

5)学到的东西

仅记录中序遍历下前一个结点即可

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页