为这个难题建议逻辑或算法

时间:2012-11-20 14:33:04

标签: c# algorithm logic

有两个数组

Array1 {5,6,7,8}

Array2 {2,1,1,0}

这是满足特定条件的模式

8,6,5,7

条件:考虑到Array2的相应元素上面的模式,Array1的8表示它在模式的左边有0个大于8的元素,类似于Array2与Array1的6相应的元素表示它有在模式中左边有1个大于6的元素。依此类推......

鉴于2个阵列有一种生成模式的方法。任何算法逻辑都会受到赞赏。

2 个答案:

答案 0 :(得分:3)

这是一个应该有效的算法:

  • 对数字进行排序。 (修改:按数字,然后按左计算
  • 对于每个号码,如果左侧需要n个较大的数字,请将其放在左侧n+1个空闲位置。
  • 如果剩下那么多空闲插槽,则两个原始阵列不允许存​​在这样的模式。

以下是您的示例的工作原理:

  • 从最小的数字开始,5。左边需要两个较大的项目。由于 all 其他项目较大,因此从左侧开始为第三项。 _ _ 5 _
  • 下一个最小值为6.左侧需要一个较大的项目。由于所有剩余项目都较大,因此需要进入第二个空闲时段。 _ 6 5 _
  • 下一个最小值为7.左侧需要一个较大的项目。由于所有剩余项目都较大,因此需要进入第二个空闲时段。 _ 6 5 7
  • 接下来是8.左边不需要更大的项目。它需要进入第一个空闲位置。 8 6 5 7

这是C#中的粗略实现:

public static int[] algorithm(int[] numbers, int[] counts)
{
    var pairs = numbers                         // EDIT:
        .Zip(counts, (n, c) => new { n, c })    // This is needed to
        .OrderBy(p => p.n)                      // correctly handle
        .ThenBy(p => p.c)                       // duplicate numbers
        .ToArray();
    int[] output = new int[pairs.Length];
    List<int> freeIndices = Enumerable.Range(0, pairs.Length).ToList();
    for (int i = 0; i < pairs.Length; i++)
    {
        if (pairs[i].c < freeIndices.Count)
        {
            int outputIndex = freeIndices[pairs[i].c];
            freeIndices.RemoveAt(pairs[i].c);
            output[outputIndex] = pairs[i].n;
        }
        else
        {
            throw new ArgumentException();
        }
    }
    return output;
}

修改:我的原始代码无法正确处理重复的数字;这个版本现在应该这样做。

答案 1 :(得分:1)

而不是将其视为两个数组,而是将其视为Number / LeftCount对的单个列表。

首先只考虑其中的一组(LeftCount == 0)。在该集合中,选择具有最小数字(n)的那个。

n写入屏幕。

从列表中删除此对。

对于Number小于n的所有剩余对,减少LeftCount。

重复,直到列表中没有对。

如果你理解这个算法的想法,那么将它编码为两个独立的数组就不会太难了。