没有转换步骤来限定数组

时间:2011-08-01 18:06:51

标签: c#

嗨,任何人都可以告诉我如何在C#中解决这个问题。 我有一个由N个元素组成的数组。数组中的元素可以是正数和负数。 如果A = [11,3,7,1] 我想计算使数组元素相等所需的最小转换步数。 数组中的每个元素都可以递增或递减1.

阵列A需要5个转换步骤才能得到A = [6,6,6,6]

在非常转换中,每个元素必须递增或递减1.

[11, 3, 7, 1] (initial array)
[10, 4, 6, 2] (after step 1)
[9, 5, 7, 3] (after step 2)
[8, 6, 6, 4] (after step 3)
[7, 7, 5, 5] (after step 4)
[6, 6, 6, 6] (after step 5)

某些阵列中有些可能无法实现。

例如,[1,4,7]不可能将元素均衡为一个数字。在这种情况下,它应该返回-1

提前致谢。

4 个答案:

答案 0 :(得分:3)

大概你只是:

  • 找到最大元素
  • 找到最小元素
  • 所需步数将是最大值与最小值之差的一半,向上舍入

你会找到最大和最小元素的平均值,向上或向下舍入 - 它不会影响步数 - 然后在每个转换步骤中,你将每个数组元素调整到该平均值。

编辑:很难看出如何提高效率。在每个步骤中,maxmimum和minimum元素彼此之间的距离不能超过2(最大值减1,最小值减1)所以步数至少差异的一半,四舍五入。我的解决方案还说 你到达那个州只有一半的差异,四舍五入,所以这是一个具体的解决方案,没有更好的。

编辑:这是执行转换的代码。虽然效率不高,但它确实有效......

using System;
using System.Linq;

class Test
{
    static void Main()
    {
        int[] current = new[] { 1, 3, 9, 11, 5 };

        // Check all odd or all even    
        if (current.Select(x => x % 2).Distinct().Skip(1).Any())
        {
            Console.WriteLine("No solution!");
            return;
        }

        while (current != null)
        {
            Console.WriteLine(string.Join(" ", current));
            current = Transform(current);
        }
    }

    static int[] Transform(int[] input)
    {
        // We could do the "mean" calculation just once,
        // but it doesn't really matter for the sake of
        // demonstration
        int max = input.Max();
        int min = input.Min();
        if (max == min)
        {
            // Done
            return null;
        }

        int mean = (max + min) / 2;
        return input.Select(x => x > mean ? x - 1 : x + 1)
                    .ToArray();
    }
}

答案 1 :(得分:1)

这有用吗?

编辑抱歉,这个:

public int[] Equalize(int[] arr)
{
        int min = int.MaxValue;
        int max = int.MinValue;
        int parity = arr[0] % 2;
        for (int i = 0; i < arr.Length; i++)
        {
            if (arr[i] % 2 != parity) return null;
            if (arr[i] < min) min = arr[i];
            if (arr[i] > max) max = arr[i];
        }
        int diff = (max - min) / 2;            
        int midVal = diff + min;
        return arr.Select(i => midVal).ToArray();
}

答案 2 :(得分:0)

ROUND_DOWN(SUM(each) / N)是否按预期工作?

答案 3 :(得分:0)

Jon Skeet的Java 8版 solution

public static void main(String[] args) throws FileNotFoundException {

         System.out.println(getTransformationCount(new int[] {1, 3, 9, 11, 5 }));

    }

    public static int getTransformationCount(int[] A) {

        int count = 0;
        A = Transform(A);

        if (IntStream.of(A).map(n -> n % 2).distinct().skip(1).count() > 0) {
            return -1;
        }

        while (A != null) {
            A = Transform(A);
            count++;
        }
        return count;
    }

    public static int[] Transform(int[] input) {

        int min = Arrays.stream(input).max().getAsInt();
        int max = Arrays.stream(input).min().getAsInt();
        if (max == min) {
            return null;
        }

        int mean = (max + min) / 2;

        return Arrays.stream(input).map((n) -> {
            if (n > mean)
                return n - 1;
            else
                return n + 1;

        }).toArray();
    }