有1、2、3、4个数字,能组成多少个互不相同 且无重复数字的三位数?都是多少?
前言
今天看到一个超级简单的算法题,但是我当时思路往递归,逐级筛选里面想了。结果百度查查答案,超级简单。
真是惭愧惭愧,不过我还是坚持用递归实现了,因为用递归的方案,可以适用于任何给定数据和指定位数。
传统解法
如下所示,因为题目是找1、2、3、4组合的三位数,因此可以用三重循环,遍历所有组合,筛选不重复组合即可。
但是该方案,如果给定数据改变,组合位数改变,那代码就得大改,所以不是一个通用的好方法。
copyfunc useNormal() []int {
var ret []int
for i := 1; i < 5; i++ {
for j := 1; j < 5; j++ {
for k := 1; k < 5; k++ {
if i != j && j != k && i != k {
ret = append(ret, i*100+j*10+k)
}
}
}
}
return ret
}
递归求解
下面方案是通过递归,依次为某一位分配数字,并将剩余组合依次赋值下一位。
该方法只需要改变data
数据,以及numLen
的指定位数就可以灵活地计算所有组合。
copyfunc useRecursion() []int {
var (
data = []int{1, 2, 3, 4}
numLen = 3
tmp = make([]int, numLen)
ret []int
)
findNum(data, tmp, numLen, &ret)
return ret
}
func findNum(data, tmp []int, dep int, ret *[]int) {
for i, v := range data {
if dep--; dep < 0 {
sum := 0
for i := len(tmp) - 1; i >= 0; i-- {
sum = sum*10 + tmp[i]
}
*ret = append(*ret, sum)
return
}
tmp[dep] = v // 当前选择赋值
next := make([]int, 0, len(data))
next = append(next, data[:i]...)
next = append(next, data[i+1:]...)
findNum(next, tmp, dep, ret) // 剔除当前元素,进入下一级筛选
dep++
}
}
完整代码
执行结果如下,两种方案结果完全一致:
[123 124 132 134 142 143 213 214 231 234 241 243 312 314 321 324 341 342 412 413 421 423 431 432] 24
[123 124 132 134 142 143 213 214 231 234 241 243 312 314 321 324 341 342 412 413 421 423 431 432] 24
copypackage main
import "fmt"
func main() {
ret0 := useNormal()
fmt.Println(ret0, len(ret0))
ret1 := useRecursion()
fmt.Println(ret1, len(ret1))
}
func useNormal() []int {
var ret []int
for i := 1; i < 5; i++ {
for j := 1; j < 5; j++ {
for k := 1; k < 5; k++ {
if i != j && j != k && i != k {
ret = append(ret, i*100+j*10+k)
}
}
}
}
return ret
}
func useRecursion() []int {
var (
data = []int{1, 2, 3, 4}
numLen = 3
tmp = make([]int, numLen)
ret []int
)
findNum(data, tmp, numLen, &ret)
return ret
}
func findNum(data, tmp []int, dep int, ret *[]int) {
for i, v := range data {
if dep--; dep < 0 {
sum := 0
for i := len(tmp) - 1; i >= 0; i-- {
sum = sum*10 + tmp[i]
}
*ret = append(*ret, sum)
return
}
tmp[dep] = v // 当前选择赋值
next := make([]int, 0, len(data))
next = append(next, data[:i]...)
next = append(next, data[i+1:]...)
findNum(next, tmp, dep, ret) // 剔除当前元素,进入下一级筛选
dep++
}
}
总结
凡事有简单方案,也有复杂方案,简单往往不能通用,多想想通用方案,尝试解决一类问题而不是某一个问题。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~