diff --git a/golang_learn/data_likou/数据流的中位数.go b/golang_learn/data_likou/数据流的中位数.go index d2628da..591dac8 100644 --- a/golang_learn/data_likou/数据流的中位数.go +++ b/golang_learn/data_likou/数据流的中位数.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "sort" ) /*** @@ -28,11 +27,19 @@ import ( */ func main() { finder := Constructor() - finder.AddNum(1) - finder.AddNum(2) - fmt.Println(finder.FindMedian()) - finder.AddNum(3) - fmt.Println(finder.FindMedian()) + finder.AddNum(-1) + fmt.Println(finder.Nums, "=>", finder.FindMedian()) + finder.AddNum(-2) + fmt.Println(finder.Nums, "=>", finder.FindMedian()) + finder.AddNum(-3) + fmt.Println(finder.Nums, "=>", finder.FindMedian()) + finder.AddNum(-4) + fmt.Println(finder.Nums, "=>", finder.FindMedian()) + finder.AddNum(-5) + fmt.Println(finder.Nums, "=>", finder.FindMedian()) + finder.AddNum(-6) + fmt.Println(finder.Nums, "=>", finder.FindMedian()) + } type MedianFinder struct { @@ -51,8 +58,15 @@ func (this *MedianFinder) AddNum(num int) { i = append(i, num) this.Nums = append(i, this.Nums...) } else { - a := append(this.Nums[:index], num) - this.Nums = append(a, this.Nums[index:]...) + // ⚠️注意:存在元素替换问题,在设置 a 时,因为内存存储是连续的,会导致将 b 的值覆盖掉 + // a, b := this.Nums[:index], this.Nums[index:] + // this.Nums = append(append(a, num), b...) + + // 避免重复,将数组复制 + a, b := make([]int, index), make([]int, len(this.Nums)-index) + copy(a, this.Nums[:index]) + copy(b, this.Nums[index:]) + this.Nums = append(append(a, num), b...) } } @@ -60,9 +74,9 @@ func (this *MedianFinder) FindMedian() float64 { i := len(this.Nums) ii := i / 2 if i%2 == 0 { - return float64(this.Nums[ii]) + return float64(this.Nums[ii]+this.Nums[ii-1]) / 2 } - return float64(this.Nums[ii]+this.Nums[ii-1]) / 2 + return float64(this.Nums[ii]) } /** @@ -72,24 +86,34 @@ func (this *MedianFinder) FindMedian() float64 { * param_2 := obj.FindMedian(); */ -// BinaryQuery 二分查找的实现,如果查找成功返回索引;否则返回-1 +// BinaryQuery 使用二分查找 对顺序列表进行定位范围,未定位导未知,返回-1 func BinaryQuery(list []int, target int) int { - // 定义并初始化low和high,声明mid - low, high := 0, len(list)-1 - - // 前提必须进行排序 - sort.Ints(list) + low, high := 0, len(list) + if high == 0 { + return -1 + } + high -= 1 // 具体下标 + lowVal, highVal := list[0], list[high] + if target <= lowVal { + return 0 + } + if target >= highVal { + return high + 1 + } + // 使用二分查找 对顺序列表进行定位范围,未定位导未知,返回-1 for low <= high { mid := (low + high) / 2 - if list[mid] == target { - return mid + if high == low { + return low } else if list[mid] > target { high = mid - 1 - } else { + } else if list[mid] < target { low = mid + 1 + } else { + return mid } }