List generic collection in C Sharp (C#) - Time & Space Complexity
Start learning this pattern below
Jump into concepts and practice - no test required
When working with a List in C#, it's important to know how the time to do actions changes as the list grows.
We want to understand how fast operations like adding or searching items happen as the list gets bigger.
Analyze the time complexity of the following code snippet.
List<int> numbers = new List<int>();
for (int i = 0; i < n; i++)
{
numbers.Add(i);
}
int index = numbers.IndexOf(target);
This code adds numbers from 0 to n-1 into a list, then searches for a target number's position.
- Primary operation: Adding items in a loop and searching through the list.
- How many times: Adding happens n times; searching may check up to n items.
Adding items grows roughly in a straight line with n, because each add is quick most times.
Searching grows in a straight line too, because it may check each item until it finds the target.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 adds, up to 10 checks to find target |
| 100 | About 100 adds, up to 100 checks to find target |
| 1000 | About 1000 adds, up to 1000 checks to find target |
Pattern observation: Both adding and searching grow linearly as the list size increases.
Time Complexity: O(n)
This means the time to add or search grows directly with the number of items in the list.
[X] Wrong: "Adding items to a List always takes the same time no matter how big it is."
[OK] Correct: Most adds are fast, but sometimes the list needs to resize its storage, which takes more time.
Understanding how List operations scale helps you explain your choices clearly and shows you know how data grows in real programs.
"What if we used a LinkedList instead of a List? How would the time complexity for adding and searching change?"
Practice
List<T> in C#?Solution
Step 1: Understand List<T> behavior
A List<T> stores items in the order they are added and allows access by index.Step 2: Compare options with List<T> features
Only It stores items in order and allows easy access by position. correctly describes this behavior; others describe different collection types or incorrect features.Final Answer:
It stores items in order and allows easy access by position. -> Option DQuick Check:
List<T> = ordered, indexed collection [OK]
- Thinking List<T> enforces uniqueness
- Assuming List<T> auto-sorts items
- Believing List<T> has fixed size
Solution
Step 1: Recall correct List<T> syntax
In C#, to declare a generic List, you must specify the type and use the new keyword with constructor.Step 2: Check each option for syntax correctness
List<int> numbers = new List<int>(); correctly declares and initializes a List of int. Others miss type, constructor, or use wrong syntax.Final Answer:
List<int> numbers = new List<int>(); -> Option AQuick Check:
Generic List declaration = new List<T>() [OK]
- Omitting new keyword
- Not specifying generic type in constructor
- Using non-generic List without type
var fruits = new List<string> { "apple", "banana", "cherry" };
fruits.RemoveAt(1);
Console.WriteLine(fruits[1]);Solution
Step 1: Understand RemoveAt effect on list
RemoveAt(1) removes the item at index 1, which is "banana". The list becomes ["apple", "cherry"].Step 2: Access the item at index 1 after removal
After removal, fruits[1] is "cherry" because the list shifted left.Final Answer:
cherry -> Option CQuick Check:
RemoveAt shifts items left, fruits[1] = cherry [OK]
- Assuming removed item still exists
- Expecting original index items unchanged
- Confusing RemoveAt with Remove
List<string> colors = new List<string>();
colors.Add("red");
colors[1] = "blue";
Console.WriteLine(colors[1]);Solution
Step 1: Analyze list content after Add
After colors.Add("red"), list has one element at index 0 only.Step 2: Check assignment to colors[1]
colors[1] does not exist yet, so assigning to it causes IndexOutOfRangeException.Final Answer:
IndexOutOfRangeException because index 1 does not exist yet. -> Option AQuick Check:
Assigning to non-existing index throws exception [OK]
- Trying to assign to index without adding
- Confusing Add and index assignment
- Expecting automatic list expansion
numbers containing {1, 2, 3, 4, 5}, which code snippet correctly doubles each number in the list?Solution
Step 1: Understand how to modify List elements
Using a for loop with index allows modifying elements directly by assignment.Step 2: Evaluate each option's effect
for (int i = 0; i < numbers.Count; i++) { numbers[i] = numbers[i] * 2; } modifies elements in place. foreach (int n in numbers) { n = n * 2; } modifies copy of elements (no effect). numbers = numbers.Select(n => n * 2).ToList(); creates a new list but requires LINQ and ToList(). numbers.ForEach(n => n = n * 2); modifies copies in ForEach (no effect).Final Answer:
for (int i = 0; i < numbers.Count; i++) { numbers[i] = numbers[i] * 2; } -> Option BQuick Check:
Use for loop with index to update List elements [OK]
- Using foreach expecting to modify list items
- Using ForEach with lambda that doesn't assign back
- Not creating new list when using LINQ Select
