hackerrank中的ArrayIndexOutOfBounds异常割断了枝条

时间:2019-11-18 08:37:41

标签: c# arrays

我正在尝试在Hackerrank中实现问题。可以找到问题here 我的代码是这个

static int[] cutTheSticks(int[] arr) 
{
    int n = arr.Length, k = 0;
    int[] result = new int[n];
    Array.Sort(arr);
    Array.Reverse(arr);

    while(arr.Length != 0)
    {
        result[k] = arr.Length;
        k++;

        for(int i = 0; i < n; ++i)
        {
            arr[i] -= arr[arr.Length - 1];
        } 
    }

    return result;
}

它显示错误为-

  

System.IndexOutOfRangeException:索引超出数组的范围。
  在solution.cs:24中的Solution.cutTheSticks(System.Int32 [] arr)[0x00020]中

第24行是:

result[k] = arr.Length;

如何删除它?

3 个答案:

答案 0 :(得分:1)

您的代码有几个问题。仅举几例:

您将结果数组的大小固定为(int[] result=new int[n];,但是它的大小完全取决于列表中包含多少个重复值。

您应该在每次迭代中从数组中删除最小值。但是,您只是在修改值(arr[i] -= arr[arr.Length - 1];),而不是删除它们,因此数组长度将保持不变,因此while (arr.Length != 0)将始终为true,从而产生无限循环。这将导致k++不断递增,直到达到大于数组长度的值为止,然后导致您得到异常。

由于您应该更改输入数组的大小,因此建议改用List<int>,这是一个示例:

List<int> output = new List<int>();
List<int> input = new List<int>(arr);

while (input.Count > 0)
{
    output.Add(input.Count);
    int min = input.Min();
    input.RemoveAll(x => x == min);
    input.ForEach(x => x -= min);
}

return output.ToArray();

答案 1 :(得分:0)

有必要在分配值之前添加条件 <configuration> <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/> </startup> </configuration> ,以避免k < n异常。此外,强烈需要避免无限IndexOutOfRangeException循环的条件:

while

更新:

可以在每次迭代后弹出一个元素,如下所示:

static int[] cutTheSticks(int[] arr) {
    int n = arr.Length,
            k = 0;
    int[] result = new int[n];
    Array.Sort(arr);
    Array.Reverse(arr);
    while (arr.Length != 0)
    {
            if (k < n)
                result[k] = arr.Length;
            else
                break;
            k++;
            for (int i = 0; i < n; ++i)
            {
                arr[i] -= arr[arr.Length - 1];
            }
    }
    return result;
}

答案 2 :(得分:0)

我会那样做:

static int[] cutTheSticks(int[] arr)
{
    List<int> results = new List<int>();
    int cutted = 0;
    while (cutted != 1)
    {
        cutted = 0;
        int min = GetMin(arr);
        if (min == 0)
        {
            break;
        }
        for (int i = 0; i < arr.Length; i++)
        {
            if (arr[i] >= min)
            {
                arr[i] -= min;
                cutted++;
            }
        }
        results.Add(cutted);
    }
    return results.ToArray();
}

static int GetMin(int[] arr)
{
    int min = int.MaxValue;
    for (int i = 0; i < arr.Length; i++)
    {
        if (arr[i] != 0 && arr[i] < min)
        {
            min = arr[i];
        }
    }
    return min;
}