递归的正确思维方式



今天我只是在做一些递归练习。虽然我可以判断问题是否与递归有关,并最终解决了它们。但这通常需要我的时间。因为我必须递归思考。

所以在这里我正在解释如何解决递归问题

public class FabonicciNumberFinder {
public static void main(String[] args) {
int number=6;
//System.out.println(findLastFabNumber(number-2,1,1));

System.out.println(findFabNumber(number));
}
private static int findFabNumber(int number) {
if(number <=1)
return number;
return findFabNumber(number-1) + findFabNumber(number-2);
}
//1 1 2 3 5 8
private static int findLastFabNumber(int number,int firstNumber, int lastNumber) {
if(number == 0)
return lastNumber;
return findLastFabNumber(number-1, lastNumber, firstNumber+lastNumber);
}

}

如果你看上面两个在某个位置找到法波那契数的解决方案。上面给出了两种方法。一个是findFabNumber(),另一个是findLastFabNumber()。findLastFabNumber() 由我编码,另一个通常可以在线使用。 这是我的思考过程。

在斐波那契级数中,我必须保持两个数字。在第一次调用中,两个 one 将被传递,但是当递归方法被调用时,必须更新数字。因为下一个数字将是最后两个数字的总和。但我必须在某个位置找到斐波那契数。所以我还必须在递归方法调用中传递一个位置计数器,这会减少。之后,我认为递归的最后一个调用当计数器递减变为 0 时。那一刻我必须返回最后一个数字。因此,它是编码的。但是当我在网上看到解决方案时。这是以另一种方式给出的(findFabNumber())。它有两个递归调用。但根据概念,它非常易读。因为根据概念,最后两个数字的总和将是您的下一个数字。所以我只是通过了 n 并直接编码

return findFabNumber(number-1) + findFabNumber(number-2) 

除了基本条件之外,我不必递归思考。下面是两个递归调用。同样,如果我们想找到数组子集的数量。我们可以通过两个递归方法调用来实现。我们不会以递归的方式深入思考。 我见过人们在纸上从上到下思考树结构,但我无法为所有递归问题考虑树结构。 所以我必须以我的方式思考它是否是递归问题。

你解决像我或任何其他人一样的递归问题的思维过程是什么。你也递归地思考。

这可能是一个愚蠢的问题,但对我来说很重要。因为如果做事的思维方式是正确的,那么事情对我们来说就会很容易。我通常这么认为。

您的findLastFabNumber使用递归函数调用,但它不能递归解决斐波那契问题。您的解决方案是在递归方法调用中"伪装"的问题的迭代解决方案。

一种方法是,您的findLastFabNumber需要额外的参数,如果这些参数不是斐波那契的起始条件,则您的函数将不会计算第n个斐波那契数。

一个问题的真正递归解决方案在较小的范围内解决了完全相同的问题。因此,递归的正确思维方式是尝试通过在"较小"尺度上解决完全相同的问题来解决问题,然后计算到下一个更高尺度的差异。

这是我的思考过程。在斐波那契数列中,我必须保持两个数字...

这就是问题所在。您只需要在斐波那契的迭代解中保持 2 个数字,但在斐波那契问题的抽象描述中,您不需要维护两个数字。您首先想到的是迭代解决方案,而不是抽象问题。

另外,顺便说一句,虽然你的解决方案是创造性的,但它比使用普通循环的经典斐波那契迭代解决方案更糟糕(就可读性而言,以及在 Java 等语言中的堆栈使用方面)。

最新更新