递归问题-给定数组n和数字k

时间:2018-11-12 15:10:16

标签: java sorting recursion

给出一个数组大小n,并给出一个正数max(max表示我们可以用来放置数组的数字范围)。

我想计算可以在数组中放置多少个排序数字组合。

例如:

如果n = 3, max = 2。(我们只能使用1/2,最大只能使用2),所以排序数组有4种组合

 1. {1,1,1}
 2. {1,1,2}
 3. {1,2,2}
 4. {2,2,2}

我编写了一些代码,并成功通过了此特定示例,但其他任何max > 2均未返回正确答案的示例。

我确定的问题是,当递归到达最后一个索引时,它不尝试第三个数字,而是将其折回。

我的代码:

private static int howManySorted(int n, int max, int index, int numToMax, int prevNum) {        
    // If the value is bigger then max return 0
    if(numToMax > max) {
        return 0;
    }
    if (numToMax < prevNum) {
        return 0;
    }
    //If Index reached the end of the array return 1
    if(index == n) {
        return 1;
    }

    int sortTwo =  howManySorted(n, max, index+1, numToMax, numToMax);
    int sortOne =  howManySorted(n, max, index+1, numToMax+1, numToMax);
    return ((sortOne+sortTwo));
}

public static int howManySorted(int n, int max) {
    return howManySorted(n, max, 0, 1, 0);
}

6 个答案:

答案 0 :(得分:1)

从“ {1”开始,并在每次递归中添加元素“ {{1,1””和/或值“ {2”。当它达到n个元素数组时,我们添加到计数器。 n是数组中元素的数量,max是每个元素的最大值。最小为1。element是要操作的数组中的当前单元格。我们从1开始(在实际数组中为0)。 value是当前元素的当前值。我们从1开始。

// external function according to the given question
public static int count (int n, int max) 
{
    return count(n,max, 1, 1);
}

private static int count (int n, int max, int element, int value) 
{
    int counter = 0;
    // only if our array reached n elements we count the comination
    if (element == n) 
        counter++;
    else // we need to continue to the next element with the same value
        counter += count(n, max, element +1, value);
    if (value < max) // if our current element didn't reach max value
        counter += count (n, max, element, value+1); 
    return counter;
}

答案 1 :(得分:0)

我认为您需要更改两个递归调用(这就是为什么它仅达到值2的原因),并执行与您的max参数一样多的调用:

private static int howManySorted(int n, int max, int index, int numToMax, int prevNum) {
    // If the value is bigger then max return 0
    if (numToMax > max) {
        return 0;
    }
    if (numToMax < prevNum) {
        return 0;
    }
    //If Index reached the end of the array return 1
    if (index == n) {
        return 1;
    }

    int result = 0;
    for (int i = 0; i < max; i++)
        result += howManySorted(n, max, index + 1, numToMax + i, numToMax);

    return result;
}

答案 2 :(得分:0)

我相信您可以简化对此类问题的回答

private static long howManySorted(int length, int min, int max) {
    if (length == 1) {
        return max - min + 1;
    }

    // if (min == max) {
    //    return 1;
    // }

    long result = 0;
    for (int i = min; i <= max; i++) {
        result += howManySorted(length - 1, i, max);
    }
    return result;
}

public static long howManySorted(int length, int max) {
    if ((length < 1) || (max < 1)) {
        throw new IllegalArgumentException();
    }

    return howManySorted(length, 1, max);
}

客户端应调用public方法。

因此您可以看到终止条件是剩余的length为1或min达到max时的终止条件。即使删除第二个终止条件也不会改变结果,但可以提高性能和递归次数。

答案 3 :(得分:0)

只需测试我的代码,我认为它可以解决您的问题:

class Test {
private static int howManySorted(int n, int max) {
    //Better time complexity if u use dynamic programming rather than recursion.

    if (n == 0) return 1;

    int res = 0; // "res" can be a very large.

    for (int i = n; i >= 1; i--) {
        for (int j = max; j >= 1;j--) {
            res += howManySorted(i-1, j-1);
        }
    }

    return res;
}

public static void main(String[] args) {
    System.out.println(howManySorted(3, 2));
}

}

如果您使用动态编程,并且运行时要小心,则此代码将运行得更快,它可能是一个非常大的整数。

答案 4 :(得分:0)

你们忘记了他只需要递归就可以解决。 可能是CS类的Java分配。

我也有这个问题。

这是我想出的答案:

/**
 * @param n Number of values in the array
 * @param max Maximum value of each cell in the array
 * @return int
 */
public static int howManySorted(int n, int max) {
    return howManySorted(max, max, 1, n - 1);
}

/**
 *
 * @param value The current value
 * @param max The maximum possible value (not allowed to use global parameters, so the parameter value always stays the same)
 * @param min The minimum value allowed in this index. Determined by the value of the previous index (when first called, use value 1)
 * @param index The index of the value being manipulated
 * @return
 */
public static int howManySorted(int value, int max, int min, int index) {
    //If any of these cases are found true, it means this value is invalid, don't count it
    if (index < 0 || value < min) {
        return 0;
    }
    //First lower the value in the same index, the result is the number of valid values from that branch
    int lowerValue = howManySorted(value - 1, max, min, index);
    //Now check all the valid values from the next index - value is max-1 to prevent counting twice some numbers
    int lowerIndex = howManySorted(max - 1, max, value, index - 1);
    //Return 1 (this number we are at right now) + all of its children
    return 1 + lowerValue + lowerIndex;
}

答案 5 :(得分:0)

我将每个系列(例如'1,1,2')视为一个数组,所以一开始我写了这样的:

ssh -L 8085:remote-machine-ip:8080 remote-machine-ip

但最终,我们不需要“索引”或“构建器”,它们只是为了强调我是如何解决它的...

public static void main(String[] args)
{
    System.out.println(howManySorted(3, 2, 1, "")); // 4
    System.out.println(howManySorted(2, 3, 1, "")); // 6
}
private static int howManySorted(int n, int max, int index, String builder)
{
    if (max == 0) // if we exceeds max, return 0.
        return 0;

    if (n == 0) // num represents how many individual numbers we can have, if it is zero it means we have the required length (e.g. if n = 3, we have 'x1,x2,x3').
    {
        System.out.println(builder.substring(0, builder.length() - 2));
        return 1;
    }

    int r1 = howManySorted(n - 1, max, index, builder + index + ", "); // i added additional var 'index' to represent each number in the list: (1,1,1)
    int r2 = howManySorted(n, max - 1, index + 1, builder); // I'm increasing the index and decreasing the max (1,1,**2**)

    return r1 + r2;
}