魔法数字的时间有效递归

时间:2014-11-19 13:45:23

标签: java recursion

我正在解决神奇数字问题,其中第n个位置的数字是前3个数字的总和,减1.例如:0 1 1 1 2 3 5 9 16 ...等等。

我用两种方式解决了它。

代码1)使用递归

int magicNumber(int n){
    int f = 0;
    if (n == 1)
        return 0;
    else if (n > 1 && n <= 4)
        return 1;
    else
        f = (magicNumber(n-1) + magicNumber(n-2) + magicNumber(n-3)) - 1;
    return f;
}

代码2)使用数组

void magicNumber(int n){
    long arr[] = new long[100];
    int i=1;
    for(i = 1; i <= n; i++)
    {
        if(i==1)
            arr[i] = 0;
        else if(i>1&&i<=4)
            arr[i] = 1;
        else
            arr[i] = (arr[i-1] + arr[i-2] + arr[i-3]) - 1;
    }
    System.out.println("Result is : "+arr[n]);
}
当我向程序提供一个小整数时,

代码1 工作正常,但它会输入更大的整数并且代码2 运行正常而没有任何问题

所以我需要你的建议,我怎样才能提高递归程序的性能 Code 1

2 个答案:

答案 0 :(得分:1)

你可以像这样加速你的递归:

int magicNumber2(int n, int a, int b, int c){
  if (n <= 1) return a;
  return magicNumber2(n - 1, b, c, a + b + c - 1);
}

int magicNumber(int n) {
  magicNumber2(n, 0, 1, 1);
}

答案 1 :(得分:0)

您遇到更高数字的延迟,因为每次递归调用都会在3次递归调用中结束。因此,时间呈指数上升。试试这种方法:

维护查找表。这里我有一个数组magic_num[100],其所有元素都初始化为-1

int magicNumber(int n){ 
    if(n == 1)
    {   
        magic_num[n] = 0;
        return 0;
    }   
    else if(n>1 && n<=4)
    {   
        magic_num[n] = 1;
        return 1;
    }   
    else if(magic_num[n] == -1) 
    {
        magic_num[n] = magicNumber(n-1) + magicNumber(n-2) + magicNumber(n-3) - 1;
        return magic_num[n];
    }
    else
        return magic_num[n]; 
}