Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 最小化二叉树范围和的内存消耗和执行时间_Algorithm_Go_Binary Search Tree - Fatal编程技术网

Algorithm 最小化二叉树范围和的内存消耗和执行时间

Algorithm 最小化二叉树范围和的内存消耗和执行时间,algorithm,go,binary-search-tree,Algorithm,Go,Binary Search Tree,我需要最小化计算二叉搜索树()的范围和的函数的内存消耗和执行时间 我目前的结果是: 运行时间:88毫秒,比BST范围总和的上网提交的69.00%快 内存使用率:7.9 MB,不到BST范围总和在线提交的5.67% 我当前的代码: func rangeSumBST(根*TreeNode,最小整数,最大整数)整数{ 总和:=0 arr:=[]*树节点{root} 变量节点*树节点 对于len(arr)>0{ 节点=arr[len(arr)-1] arr=arr[:len(arr)-1] 如果node

我需要最小化计算二叉搜索树()的范围和的函数的内存消耗和执行时间

我目前的结果是:

运行时间:88毫秒,比BST范围总和的上网提交的69.00%快

内存使用率:7.9 MB,不到BST范围总和在线提交的5.67%

我当前的代码:

func rangeSumBST(根*TreeNode,最小整数,最大整数)整数{
总和:=0
arr:=[]*树节点{root}
变量节点*树节点
对于len(arr)>0{
节点=arr[len(arr)-1]
arr=arr[:len(arr)-1]
如果node.Val>=min&&node.Val-min{
arr=append(arr,node.Left)
}
如果node.Right!=nil&&node.Val
我试着递归地解决这个问题,这很优雅,但当然比迭代的解决方案更慢、更需要内存

我所拥有的迭代解决方案尽可能精简和简单。我声明并重用
节点
变量,而不是在for循环中声明它。我将节点添加到切片的末尾,而不是开始


我还可以做些什么来加快速度和减少内存使用?还是有更有效的算法?还是Leetcode测量执行时间和内存消耗的方式有误?

由于它是一个BST,您可以使用在O(1)空间复杂度中执行。对于BST,在Order Morris Travers中,对于单个查询,您不能比O(N)时间复杂度做得更好,除非在树本身中进行某种预处理。您当前的实现使用堆栈,所以在最坏的情况下,当树基本上是一条路径时,您当前的空间复杂度是O(N)

在Go中的实施(能够击败99%):

func rangeSumBST(root *TreeNode, min int, max int) int {
    if root == nil {
        return 0
    }
    
    var pre *TreeNode
    curr := root
    sum := 0
    for curr != nil {
        if curr.Left == nil {
            if curr.Val >= min && curr.Val <= max {
                sum += curr.Val
            }
            if curr.Val > max {
                break
            }
            curr = curr.Right
        } else {
            pre = curr.Left
            
            for pre.Right != nil && pre.Right != curr {
                pre = pre.Right
            }
            
            if pre.Right == nil {
                pre.Right = curr
                curr = curr.Left
            } else {
                pre.Right = nil
                if curr.Val >= min && curr.Val <= max {
                    sum += curr.Val
                }
                if curr.Val > max {
                    break
                }                
                curr = curr.Right
            }
            
        }
    }
    return sum
}
func rangeSumBST(根*TreeNode,最小整数,最大整数)整数{
如果根==nil{
返回0
}
前*树节点变量
curr:=根
总和:=0
对于curr!=零{
如果当前左侧==零{
如果当前值>=最小值和当前值最大值(&C){
打破
}
当前=当前对
}否则{
前=当前左侧
对于右前!=零和右前!=当前{
pre=pre.Right
}
如果前右==nil{
前右=当前
当前=当前左侧
}否则{
前右=零
如果当前值>=最小值和当前值最大值(&C){
打破
}                
当前=当前对
}
}
}
回报金额
}
时间复杂度:O(节点数)

空间复杂性:O(1)


注意:不知何故,它并没有显示内存性能的任何改善,可能是因为测试还不够,并且已知leetcode在测试不太大时会显示以前提交的解决方案的旧统计信息。

因为它是一个BST,您可以在O(1)中执行空间复杂度使用对于BST,在Order Morris Travers中,除非对树本身进行某种预处理,否则单次查询的时间复杂度不能超过O(N)。您当前的实现使用堆栈,所以在最坏的情况下,当树基本上是一条路径时,您当前的空间复杂度是O(N)

在Go中的实施(能够击败99%):

func rangeSumBST(root *TreeNode, min int, max int) int {
    if root == nil {
        return 0
    }
    
    var pre *TreeNode
    curr := root
    sum := 0
    for curr != nil {
        if curr.Left == nil {
            if curr.Val >= min && curr.Val <= max {
                sum += curr.Val
            }
            if curr.Val > max {
                break
            }
            curr = curr.Right
        } else {
            pre = curr.Left
            
            for pre.Right != nil && pre.Right != curr {
                pre = pre.Right
            }
            
            if pre.Right == nil {
                pre.Right = curr
                curr = curr.Left
            } else {
                pre.Right = nil
                if curr.Val >= min && curr.Val <= max {
                    sum += curr.Val
                }
                if curr.Val > max {
                    break
                }                
                curr = curr.Right
            }
            
        }
    }
    return sum
}
func rangeSumBST(根*TreeNode,最小整数,最大整数)整数{
如果根==nil{
返回0
}
前*树节点变量
curr:=根
总和:=0
对于curr!=零{
如果当前左侧==零{
如果当前值>=最小值和当前值最大值(&C){
打破
}
当前=当前对
}否则{
前=当前左侧
对于右前!=零和右前!=当前{
pre=pre.Right
}
如果前右==nil{
前右=当前
当前=当前左侧
}否则{
前右=零
如果当前值>=最小值和当前值最大值(&C){
打破
}                
当前=当前对
}
}
}
回报金额
}
时间复杂度:O(节点数)

空间复杂性:O(1)


注意:不知何故,它并没有显示内存性能的任何改善,可能是因为测试不够,并且已知leetcode在测试规模不太大时会显示以前提交的解决方案的旧统计信息。

此外,问题陈述显示:1。树中的节点数最多为10000。2.最终答案保证小于2^31。这与可能的优化有关吗?朴素的递归解决方案实际上更快(运行时间:84毫秒,比BST范围和的93.67%的在线提交速度快),但会消耗稍多的内存。要回答这个问题,您应该分析代码以找出它在哪里花费时间。一个明显的优化是预分配arr,而不是分配JIT。由于这是一个BST,您可以使用BST的有序Morris遍历在O(1)空间复杂度内完成,因此您不能比O(N)时间复杂度做得更好。您当前的实现使用的是堆栈,所以在最坏的情况下,当树基本上是一条路径时,您当前的空间复杂度是O(N)。树中的节点数最多为10000。2.最终答案保证小于2^31。这与可能的优化有关吗?简单的递归解决方案实际上更快(运行时间:84毫秒,比BST范围和的93.67%的在线提交速度快),但会消耗稍多的内存