面试题答案
一键面试1. 尾递归优化
尾递归是指递归调用是函数的最后一个操作。Rust 编译器可以优化尾递归,将其转换为循环,从而避免栈溢出。
// 普通递归函数,计算阶乘,可能导致栈溢出
fn factorial(n: u32) -> u32 {
if n == 0 {
1
} else {
n * factorial(n - 1)
}
}
// 尾递归函数,使用累加器优化
fn factorial_tail_recursive(n: u32, acc: u32) -> u32 {
if n == 0 {
acc
} else {
factorial_tail_recursive(n - 1, n * acc)
}
}
调用 factorial_tail_recursive
时,第二个参数 acc
作为累加器,这样编译器可以优化为循环。例如:factorial_tail_recursive(5, 1)
2. 手动模拟栈
使用 Vec
等数据结构手动模拟栈,将递归逻辑转换为迭代逻辑。
// 使用栈模拟递归计算阶乘
fn factorial_with_stack(n: u32) -> u32 {
let mut stack = Vec::new();
let mut result = 1;
stack.push(n);
while let Some(num) = stack.pop() {
if num > 0 {
result *= num;
stack.push(num - 1);
}
}
result
}
3. 分治策略与迭代结合
将大数据集分解为较小的子集,然后使用迭代处理这些子集。例如在归并排序中:
fn merge_sort(mut arr: Vec<i32>) -> Vec<i32> {
if arr.len() <= 1 {
return arr;
}
let mid = arr.len() / 2;
let left = merge_sort(arr.split_off(mid));
let right = merge_sort(arr);
let mut merged = Vec::new();
let mut i = 0;
let mut j = 0;
while i < left.len() && j < right.len() {
if left[i] < right[j] {
merged.push(left[i]);
i += 1;
} else {
merged.push(right[j]);
j += 1;
}
}
merged.extend(left.into_iter().skip(i));
merged.extend(right.into_iter().skip(j));
merged
}
这里通过将数组不断分割(分治),然后迭代合并(迭代),避免了深度递归带来的栈溢出问题。