面试题答案
一键面试实现思路
- 使用循环代替递归:将递归调用转换为循环结构,手动管理调用栈。
- 模拟栈:使用数据结构(如切片)来模拟函数调用栈,存储每次调用的状态。
- 状态机:通过状态标识来决定在循环的每一步执行什么操作,模仿递归中的不同阶段。
关键代码片段
package main
import "fmt"
// 定义一个结构体来表示函数调用状态
type CallState struct {
// 存储递归函数需要的参数
param int
// 用于模拟递归返回值的临时变量
result int
// 状态标识,可用于决定在循环中执行什么操作
state int
}
func tailRecursionOptimized(n int) int {
stack := make([]CallState, 0)
stack = append(stack, CallState{param: n, state: 0})
for len(stack) > 0 {
top := stack[len(stack)-1]
stack = stack[:len(stack)-1]
if top.state == 0 {
if top.param == 0 {
top.result = 1
stack = append(stack, top)
top.state = 1
} else {
newCall := CallState{param: top.param - 1, state: 0}
stack = append(stack, top)
stack = append(stack, newCall)
}
} else if top.state == 1 {
top.result = top.param * top.result
if len(stack) > 0 {
stack = append(stack, top)
}
}
}
return stack[0].result
}
可以这样调用这个函数:
func main() {
result := tailRecursionOptimized(5)
fmt.Println(result)
}
上述代码以阶乘函数为例,通过模拟栈和状态机来实现类似尾递归优化的效果,避免栈溢出。