C#中最短的代码是什么可以将一个数组压平?
例如,我想要:
[[1,2],[2,3],[4,5]]
添加到数组中
[1,2,3,4,5]
我正在寻找完成此事的最短路径。
C#中最短的代码是什么可以将一个数组压平?
例如,我想要:
[[1,2],[2,3],[4,5]]
添加到数组中
[1,2,3,4,5]
我正在寻找完成此事的最短路径。
也许我对“最短代码”的理解方式有误,但我建议使用LINQ SelectMany
和 Distinct
:
var values = new[]
{
new[] { 1, 2 },
new[] { 2, 3 },
new[] { 4, 5 },
};
var flattenedUniqueValues = values.SelectMany(x => x).Distinct();
O(n)
的时间内完成,需要 n
的空间(其中 n
是第二维数组长度的总和)。然而,在您的示例中,似乎要删除重复值-这不是扁平化数组,但仍然可以在 O(n)
时间内完成,但需要 O(2n)
的空间,因为您需要一个哈希表进行 O(1)
的重复值查找。List<T>
并在末尾调用 .ToArray()
,但这将导致 O(2n)
的时间和 O(3n)
的空间(但由于 List<T>
内部重新分配,潜在地更多)。Int32[][] jagged = ...
HashSet<Int32> seen = new HashSet<Int32>();
List<Int32> ret = new List<Int32>();
for(int i = 0; i < jagged.Length; i++) {
for(int j = 0; j < jagged[i].Length; j++) {
Int32 val = jagged[i][j];
if( !seen.Contains( val ) ) {
ret.Add( val );
seen.Add( val );
}
}
}
return ret.ToArray(); // This takes O(n) time and will allocate O(n) additional space.
另一种解决方案是自己进行两次遍历:第一次确定输出的大小,然后第二次遍历生成输出 - 这将导致更少的复制:时间复杂度为 O(2n)
,空间复杂度也为 O(2n)
。
Int32[][] jagged = ...
HashSet<Int32> seen = new HashSet<Int32>();
// Pass 1
for(int i = 0; i < jagged.Length; i++) {
for(int j = 0; j < jagged[i].Length; j++) {
Int32 val = jagged[i][j];
seen.Add( val ); // HashSet.Add is safe/idempotent
}
}
Int32[] ret = new Int32[ seen.Count ];
// Pass 2
seen.Clear();
Int32 retIdx = 0;
for(int i = 0; i < jagged.Length; i++) {
for(int j = 0; j < jagged[i].Length; j++) {
Int32 val = jagged[i][j];
if( !seen.Contains( val ) ) {
ret[++retIdx] = val;
seen.Add( val );
}
}
}
return ret;