如果A2 已排序,则O(n) 的复杂性是可能的,因为这样你就可以只用一个循环来单独索引每个数组:
var A1 = new string[] { "a", "b", "c", "d", "e", "f", "g" }; // N elements and N is large
var A2 = new int[] { 1, 5 }; // k elements and k is small (and constant)
A2 = A2.OrderBy(x => x).ToArray();
var A3 = new string[A1.Length];
int m = 0; // To check it runs only n times.
int leftItemCount = A1.Length - A2.Length;
for (int i = 0, j = 0, k = 0, l = leftItemCount; i < leftItemCount || m < items.Length; i++)
{
m++;
if (j < A2.Length && k == A2[j])
{
j++;
k++;
A3[l++] = "_";
i--;
continue;
}
A3[i] = A1[k];
k++;
}
// Answer = [ a, c, d, e, g, _, _ ] for { 1, 5 }
// Answer = [ a, d, e, g, _, _, _ ] for { 1, 2, 5 }
测试代码:
static void ArrayTests()
{
// Item array lengths.
for (int i = 45; i < 256; i++)
{
var items = Enumerable.Range(0, i).Select(x => x.ToString()).ToArray();
// Number of tests per array.
for (int j = 0; j < 100; j++)
{
// Items to remove.
Random rnd = new Random(DateTime.Now.Millisecond);
var remove = new int[rnd.Next(1, i)];
HashSet<int> indexes = new HashSet<int>();
for (int k = 0; k < remove.Length; k++)
{
int index = 0;
do
{
index = rnd.Next(0, i);
} while (indexes.Contains(index));
indexes.Add(index);
remove[k] = index;
}
remove = remove.OrderBy(x => x).ToArray();
var result = ArrayTest(items, remove);
}
}
}
static string[] ArrayTest(string[] items, int[] remove)
{
var A3 = new string[items.Length];
int m = 0;
int leftItemCount = items.Length - remove.Length;
for (int i = 0, j = 0, k = 0, l = leftItemCount; i < leftItemCount || m < items.Length; i++)
{
m++;
if (j < remove.Length && k == remove[j])
{
j++;
k++;
A3[l++] = "_";
i--;
continue;
}
A3[i] = items[k];
k++;
}
Debug.Assert(m == items.Length);
return A3;
}