(14)Go实现的线段树解答leetcode-307

// 这类问题用线段树解决是比较好的选择
   解决方法的定义:

type NumArray struct {
	tree   []int
	data   []int
}


func Constructor(nums []int) NumArray {
	length := len(nums)

	if length==0{
		return NumArray{}
	}
	tree := &NumArray{
		tree:   make([]int, length*4),
		data:   nums,
	}

	tree.bulidSegmentTree(0, 0, length-1)

	return *tree
}

func (this *NumArray) bulidSegmentTree(index, l, r int) int {
	if l == r {
		this.tree[index] = this.data[l]
		return this.data[l]
	}

	leftI := 2*index+1
	rightI := leftI + 1
	mid := l + (r-l)/2
	leftResp := this.bulidSegmentTree(leftI, l, mid)
	rightResp := this.bulidSegmentTree(rightI, mid+1, r)

	this.tree[index] = leftResp + rightResp
	return this.tree[index]
}


func (this *NumArray) Update(i int, val int)  {
	length := len(this.data)
	if i < 0 || i >= length {
		return
	}
	this.set(0, 0, length-1, i, val)
}

func (this *NumArray) set(treeIndex, l, r, k, v int) {
	if l == r {
		this.tree[treeIndex] = v
		return
	}

	leftI := 2*treeIndex+1
	rightI := leftI + 1
	midI := l + (r-l)/2

	if k > midI {
		this.set(rightI, midI+1, r, k, v)
	} else {
		this.set(leftI, l, midI, k, v)
	}

	this.tree[treeIndex] = this.tree[leftI]+this.tree[rightI]
}

func (this *NumArray) SumRange(i int, j int) int {
	length := len(this.data)
	if i < 0 || i > j || j >= length {
		return 0
	}
	return this.queryrange(0, 0, length-1, i, j)
}

func (this *NumArray) queryrange(index, i1, i2, queryL, queryR int) int {
	if i1 == queryL && i2 == queryR {
		return this.tree[index]
	}

	leftI := 2*index+1
	rightI := leftI + 1
	mid := i1 + (i2-i1)/2

	if queryL > mid {
		return this.queryrange(rightI, mid+1, i2, queryL, queryR)
	}
	if queryR <= mid {
		return this.queryrange(leftI, i1, mid, queryL, queryR)
	}
	leftResp := this.queryrange(leftI, i1, mid, queryL, mid)
	rightResp := this.queryrange(rightI, mid+1, i2, mid+1, queryR)
	return leftResp + rightResp
}
用leetcode测试代码逻辑

通过,逻辑通。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值