Let's say I have a list of N elements (list1
).
I have then a list of M <= N elements containing all the indices of elements that I want to remove from the other list (list2
).
I want to delete elements on list1
accordingly with list2
indices in the most efficient way possible.
First approach was through a for loop:
for (int i = 0; i < list2.Count; i++)
list1.RemoveAt(list2[i]);
This work pretty good (I need list2
to be ordered, of course) but has an O(M*N) complexity in worst case (M iterations, O(n) for RemoveAt
)
Another solution was to create a temporary list, populate it with elements that should not be deleted and then use the LINQ intersect method
List<T> tempList = new List<T>();
for (int i = 0; i < list1.Count; i++)
if (list2.Contains(i))
tempList.Add(list1[i]);
list1.Intersect(tempList);
While at first I was excited by the O(N+M) complexity of the Intersect
, I eventually realized that I need at first N iterations to populate the tempList
and then any advantages goes lost (let us assume that list2 is an HashSet
in this second case I don't care about ordering but just about O(1) Contains
)
After some digging, still I wasn't able to find a way to perform a RemoveAll
like method that removes all the elements from list1
accordigly to values stored in list2
.
Is it there any chance to get it as performant as possible?
PS: for all the ones that will think "premature optimization is the root of all evil", please consider that my code is actually working fine but, as I am working on a strictly time dependend problem, saving few ns each iteration (and I am going to have around 150k iterations) can lead to a significant improvement.
EDIT: as @InBetween correctly pointed out, having an Intersect
on second solution is actually useless, reducing it the complexity goes down.