- 洗牌
- 蓄水池
- 加权
洗牌
大致有四种写法
func shuffle(nums []int) []int {n := len(nums)for i := 0; i < n; i++ {// [i, n - 1)j := i + rand.Intn(n - i)temp := nums[i]nums[i] = nums[j]nums[j] = temp}return nums}
主要区别在于循环条件和循环体的第一句话
for i := 0; i < n -1; i++ {j := i + rand.Intn(n-i)// ...}for i := n -1; i >= 0; i-- {j := rand.Intn(i)// ...}for i := n -1; i> 0; i-- {j := rand.Intn(i)// ...}
那么比较下第一种与第二种的区别。 区别就是,
第一种的产生结果数量有: n (n-1) … 1
第二种产生结果数量比第一种少了最后一个 i = n-1 的时候,当 i = n-1 的时候,取值范围是 [n-1, n-1] ,所以是 n (n-1) … 2
所以两者是一样的结果。
同理,第三种第四种类比。
蓄水池
func random (nums []int, k int) []int {res := make([]int, k)copy(res, nums)n := len(nums)for i:= k; i < n; i++ {// [0, i+1) => [0, i]j := rand.Intn(i)if j < k {res[j] = nums[i]}}return res}
加权
func searchInts(a []int, target int) int {left, right := 0, len(a)-1for left <= right {mid := left + (right-left)>>1if a[mid] >= target {if mid == 0 || a[mid-1] < target {return mid}right = mid - 1} else {left = mid + 1}}return -1}
