本文详解如何使用 Go 的 rand.Perm() 生成指定区间内无重复的随机整数序列,并通过偏移变换将 [0, n) 映射到任意闭区间 [min, max]。
本文详解如何使用 go 的 `rand.perm()` 生成指定区间内无重复的随机整数序列,并通过偏移变换将 `[0, n)` 映射到任意闭区间 `[min, max]`。
Go 标准库中的 rand.Perm(n) 函数用于生成 [0, n) 范围内所有整数的一个随机排列(即长度为 n、元素互异、覆盖 0 到 n−1 的切片)。它本身不支持直接指定起始值,但可通过简单的数学平移实现任意连续整数区间的随机重排。
例如,要获取 6 到 10(含)共 5 个不重复随机数,需先调用 r.Perm(5) 得到 [0,1,2,3,4] 的某一种随机顺序(如 [1,2,3,4,0]),再对每个元素统一加上最小值 min = 6,即可得到目标范围内的随机排列:
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
min, max := 6, 10
n := max - min + 1 // 区间长度:6,7,8,9,10 → 共 5 个数
perm := r.Perm(n) // 生成 [0, 1, 2, 3, 4] 的随机排列
// 偏移映射:将 [0, n) → [min, max]
for i := range perm {
perm[i] += min
}
fmt.Printf("随机排列(6–10): %v\n", perm)
// 输出示例:[7 8 9 10 6]
}
⚠️ 注意事项:
- rand.Perm(n) 返回的是 全排列,适用于需要“不重复且覆盖整个区间”的场景;若只需单个随机数(允许重复),应使用 r.Intn(max-min+1) + min。
- 每次运行前务必初始化独立的 rand.Rand 实例并设置唯一种子(推荐 time.Now().UnixNano()),避免因默认种子相同导致重复结果。
- Perm 时间复杂度为 O(n),当 n 极大(如百万级)时需评估性能;此时可考虑 Fisher–Yates 洗牌或蓄水池采样等替代方案。
总结:通过 Perm(len) + offset 是 Go 中实现「指定闭区间内无重复随机序列」最简洁、标准且高效的方式,兼具可读性与可靠性。











