【问题标题】:Find Kth Smallest Value in BST -- K not changing在 BST 中找到第 K 个最小值——K 不变
【发布时间】:2021-01-06 13:21:55
【问题描述】:

我已经考虑了这么久,它正在煎熬我的大脑。可能我还没有完全理解递归。

我不明白为什么 k 的值在等于 0 后不进入负数。相反,它保持为 0,直到辅助函数存在。我尝试传入一个初始值为 0 的整数并相加直到其值等于 k。然而,这导致了同样的问题,一旦它等于 k,它就会保持这种状态。

有人可以解释为什么值保持不变吗?

class Solution {
        public int kthSmallest(TreeNode t, int k) {
          TreeNode tempNode = new TreeNode();
          int iter = 0;
          getKValue(t, k, tempNode); 
          return tempNode.val;
        }
        
        private static void getKValue(TreeNode t, int k, TreeNode temp) {
            if(t == null) {
                return;
            }
        
    
            getKValue(t.left, k, temp);
            
            
            k = k - 1;
            System.out.println(k);
            if(k == 0) {
                temp.val = t.val;
                return;
            }
            getKValue(t.right, k, temp);
        
        }
    }

例如,对于下面的树,预期的输出是 1。但我得到 3,控制台打印了两次 0。

Input: root = [3,1,4,null,2], k = 1
   3
  / \
 1   4
  \
   2
Output: 1

【问题讨论】:

  • 尝试在一张纸上调试并跟踪执行,您就会知道为什么会得到 3 和 0 被打印两次。您正在递归调用辅助函数,然后执行 k = k - 1 这就是为什么您看到 0 打印了两次。最后一次返回将在节点 3,这就是返回 3 的原因
  • @SherifelKhatib -- 实际上并非如此。他被打印了两次,因为每次他调用递归方法时,都会从树的左侧和右侧生成 K 的新副本。他需要发送一个 K,这对于 LHS 和 RHS 都是通用的(就是引用调用的情况,但不幸的是 java 不支持引用调用)
  • @PapaifromBEKOAIL 我的理由是从执行的角度来看,而你的理由是从算法的角度来看......同样的

标签: java algorithm recursion binary-tree depth-first-search


【解决方案1】:

我认为问题在于您在每个递归调用中都传递了k。您不应该这样做,因为这会导致每个递归调用都获得自己的k副本。这意味着当你修改k:

k = k - 1;

堆栈中的其他调用不知道k 的变化。至于其他调用,k 仍然是 1,因为它们都有自己的副本。

要解决此问题,您应该拥有一个共享 k,所有递归调用都可以访问:

    static int sharedK; // shared!
    public int kthSmallest(TreeNode t, int k) {
      TreeNode tempNode = new TreeNode();
      sharedK = k; // setting the sharedK
      getKValue(t, tempNode); 
      return tempNode.val;
    }
    
    private static void getKValue(TreeNode t, TreeNode temp) {
        if(t == null) {
            return;
        }

        getKValue(t.left, temp);
        
        sharedK--; // note the change here
        System.out.println(sharedK);
        if(sharedK == 0) {
            temp.val = t.val;
            return;
        }
        getKValue(t.right, temp);
    }

如果k 通过引用传递也可以实现同样的效果,但不幸的是,您不能在Java 中通过引用传递。

【讨论】:

    【解决方案2】:

    我认为问题需要你输出 BST 的第 Kth Smallest 元素,这是使用 O(N) 内存空间的代码,其中 N 是 BST 中的节点数。首先,我们将使用中序遍历(递归)遍历 BST,并将节点保存在数组或向量中。 BST的中序遍历给出了排序顺序的节点。

    struct TreeNode {
        int val;
        TreeNode *left;
        TreeNode *right;
    };
    
    vector<int> nodes;
    
    void inorder(TreeNode *root) {
        if(root!=NULL)
        {
            inorder(root->left);
            nodes.push_back(root->val);
            inorder(root->right);
        }
    }
    class Solution {
    public:
        int getValue(TreeNode* root,int K)
        {
            nodes.clear();
            if(root!=NULL)
            {
                inorder(root);
                return nodes[K-1];
            }
            return -1;
        }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-02
      • 2015-01-15
      • 1970-01-01
      • 2012-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多