var n = len(arr) var tree = make([]int, 4*n) var build func(int, int, int) //i代表当前节点在tree中的对应下标,l/r表示i锁代表arr区间的左右边界 build = func(i int, l int, r int) { //当l == r时说明当前节点是叶子节点(区间长度为1) if l == r { tree[i] = arr[l] return } leftChild, rightChild := i*2+1, i*2+2 m := (l + r) / 2 build(leftChild, l, m) build(rightChild, m+1, r) tree[i] = max(tree[leftChild], tree[rightChild]) } build(0, 0, n-1)
区间查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14
//ql/qr表示需要查找的区间 var query = func(i, l, r, ql, qr int) { if qr < l || r < ql { return math.MinInt32 } if ql <= l && qr >= r { return tree[i] } m := (l+r)/2 leftChild, rightChild := i*2+1, i*2+2 left := query(leftChild, l, m) right := query(rightChild, m+1, r) return max(left, right) }
funcnumOfUnplacedFruits(fruits []int, baskets []int)int { var n = len(fruits) var tree = make([]int, 4*n) var build func(int, int, int) build = func(i int, l int, r int) { if l == r { tree[i] = baskets[l] return } leftChild, rightChild := i*2+1, i*2+2 m := (l + r) / 2 build(leftChild, l, m) build(rightChild, m+1, r) tree[i] = max(tree[leftChild], tree[rightChild]) } build(0, 0, n-1) var ret = 0 for _, v := range fruits { i := 0 for { //因为所有有效节点必定大于0,所以可以通过子节点是否大于0来判断当前节点是否为叶子节点 if i*2+2 < 4*n && tree[i*2+1] != 0 && tree[i*2+2] != 0 { if v > tree[i*2+1] { i = i*2 + 2 } else { i = i*2 + 1 } } else { break } } if tree[i] >= v { //将使用后的节点更新为-1 tree[i] = -1 i = (i - 1) / 2 for ; i > 0; i = (i - 1) / 2 { //向上逐层更新 tree[i] = max(tree[i*2+1], tree[i*2+2]) } } else { ret++ } } return ret }