有两个数组
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 个数组是否有生成模式的方法。任何算法逻辑都将不胜感激。
这是一个应该有效的算法:
n
更大的数字,把它放在左边的n+1
第 th 个空闲槽中。以下是它在您的示例中的工作方式:
_ _ 5 _
_ 6 5 _
_ 6 5 7
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;
}
编辑:我的原始代码没有正确处理重复的数字;这个版本现在应该这样做。
与其将其视为两个数组,不如将其视为 Number/LeftCount 对的单个列表。
首先只考虑 (LeftCount == 0) 的对集合。在这组中选择编号最小的一组 ( n
)。
写到n
屏幕上。
从列表中删除这对。
对于 Number 小于 的所有剩余对n
,递减 LeftCount。
重复直到列表中没有任何对。
如果你理解这个算法的想法,把它编码成两个独立的数组就不会太难了。