Why memory limit exceeded and how can i avoid this?

痴心易碎 提交于 2020-01-06 06:28:38

问题


 import java.util.*;

 public class AlmostPerfect {

 public static void main(String[] args) {
 Scanner x = new Scanner(System.in);
 while(x.hasNext()){
    int n = x.nextInt();
    int sum = recursion(n,n-1,0);
    if (sum == n) {
        System.out.println(n + " perfect");
    } else if ((n - sum) <= 2) {
        System.out.println(n + " almost perfect");
    } else {
        System.out.println(n + " not perfect");
    }
}
}

public static int recursion(int n, int x,int sum) {

    if(x==0){
        return sum;
    }
    else if (n % x == 0) {
        sum+=x;
        return recursion(n,x-1,sum);
    }
    else{
        return recursion(n,x-1,sum);
    }

}

}

I want to basically find whats wrong with my solution... There exists a solution for this but I can't understand the memory limit exceeded property. Problem link: https://open.kattis.com/problems/almostperfect Thanks.


回答1:


If you must of prefer a recursive solution, you can limit the depth of the recursion, to avoid stack overflow.
You can do it be running the recursive solution on continuous intervals, one interval at time :

import java.util.stream.IntStream;

public class AlmostPerfect {

    //defines the recursive iteration depth. increase it and you run into
    //stack over flow
    private static int RECURSION_DEPTH =5000;

    public static void main(String[] args) {

        //run comparison test between recursive and non recursive solutions
        IntStream.range(1,200000).forEach(i ->{

            double sumRecursive = recursionWithLimitedDepth(i);
            double sumIterative = iterative(i);

            if((sumRecursive != sumIterative)) {
                System.out.println("for "+ i +" "+ sumRecursive + "<>" +sumIterative );
                return;
            }

            if((i%20000) ==0) {
                System.out.println("20,000 numbers successfully checked"  );
            }
        });

        System.out.println("Test finished");
    }

    //helper method for recursive solution
    public static double recursionWithLimitedDepth(int n) {

        double sum = 0;
        int rangeStart = n-1;
        int rangeEnd = rangeStart - RECURSION_DEPTH;

        while (rangeStart > 0) {
            sum += recursionWithLimitedDepth(n, rangeStart, rangeEnd, 0);
            rangeStart = (rangeEnd - 1) >= 0 ? rangeEnd - 1 : 0;
            rangeEnd = (rangeStart - RECURSION_DEPTH) >= 0 ?  rangeStart - RECURSION_DEPTH :0;
        }

        return sum;
    }

    //run recursive solution on a limited range defined by rangeStart, rangeEnd
    public static double recursionWithLimitedDepth(int numberToTest, int rangeStart,
                                                            int rangeEnd , double sum) {
        if(rangeStart == 0){
            return sum;
        }
        else if ((numberToTest % rangeStart) == 0) {
            sum+=rangeStart;
        }

        if(rangeStart == rangeEnd){
            return sum;
        }

        return recursionWithLimitedDepth(numberToTest,rangeStart-1, rangeEnd, sum);
    }

    //simple iterative to test against
    public static double iterative(int n) {

        double sum = 0;

        for(int x = n-1; x > 0; x--) {
            if((n%x) == 0) {
                sum += x;
            }
        }

        return sum;
    }
}

Note that sum is double to avoid Integer overflow (tested with Integer.MAX_VALUE).



来源:https://stackoverflow.com/questions/51270365/why-memory-limit-exceeded-and-how-can-i-avoid-this

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!