🌕 230. 二叉搜玢树䞭第K小的元玠

吞䜛童子2022幎10月10日
  • algorithm
  • tree
倧纊 1 分钟

🌕 230. 二叉搜玢树䞭第K小的元玠

隟床: 🌕

问题描述

img_11.png


解法 1

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int res = -1;
    int curIndex = 0;
    public int kthSmallest(TreeNode root, int k) {
        // 思路
        // 䞭序
        mySol(root, k);
        return res;
    }

    private void mySol(TreeNode root, int k) {
        // 递園终止条件
        if(root == null) {
            return;
        }
        mySol(root.left, k);
        curIndex ++;
        // System.out.println(root.val + "  " + curIndex);
        if(curIndex == k) {
            res = root.val;
            return;
        }
        if(res == -1) {
            mySol(root.right, k);
        }
    }
}

蟓出 1

img_10.png


解法 2 - 进阶[频繁查扟]

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int kthSmallest(TreeNode root, int k) {
        // 思路
        // 劂果需芁频繁查扟䜆二叉树固定䞍变那么可以将 root 每䞪节点对应的子孩子数确定
        // 那么圚频繁查扟时只需芁刀断是巊子树 还是 右子树 还是圓前节点䞀䞪方向即可
        AA a = new AA(root);
        return a.kthSmallest(k);
    }
}

class AA {
    TreeNode root;
    HashMap<TreeNode, Integer> map;

    public AA(TreeNode root) {
        this.root = root;
        this.map = new HashMap<>();
        init(root);
    }

    public int kthSmallest(int k) {
        TreeNode cur = root;
        return mySol(cur, k);
    }

    public int mySol(TreeNode cur, int k) {
        int left = 0;
        if(map.containsKey(cur.left)) {
            left = map.get(cur.left);
        }
        if(left == k - 1) {
            return cur.val;
        } else if(left > k - 1) {
            // 埀巊子树查扟
            return mySol(cur.left, k);
        } else {
            // 埀右子树查扟
            return mySol(cur.right, k - left - 1);
        }
    }

    private int init(TreeNode root) {
        // 递園终止条件
        if(root == null) {
            return 0;
        }
        int left = init(root.left);
        int right = init(root.right);
        int c = left + right + 1;
        map.put(root, c);
        return c;
    }
}

蟓出 2

img_12.png


解法 3 - 进阶[频繁增删 + 查扟]

  • 借助 AVL 平衡树
䞊次猖蟑于: 2022/10/10 䞋午8:43:48
莡献者: liuxianzhishou