Free Handbook · Every example compiled & verified

Problem Solving

A repeatable way to crack coding problems in C#: read it, break it down, test small cases, then apply one of eight patterns that cover most interviews.

0 / 142 lessons🔥 0 day streak
ShareXLinkedIn

Module 14 · what you'll be able to do

  • Turn a problem statement into inputs, outputs, constraints and edge cases before writing any code
  • Test a solution with a tiny hand-rolled harness of small cases instead of guessing
  • Estimate the Big-O a problem needs from its input limits, in plain English
  • Recognise and apply eight patterns in C#: two pointers, sliding window, Dictionary lookups, stack, backtracking, sorting, BFS/DFS and DP-lite
01

Read the problem before touching the keyboard

Most failed coding rounds fail in the first two minutes: the candidate starts typing a solution to a problem they have not fully read. Slow down and write these five things down (in a comment, on the whiteboard, or out loud) before any code.

  1. 1
    Restate it

    One sentence, in your own words. "Given a list of prices, return the biggest profit from one buy followed by one later sell."

  2. 2
    Inputs and outputs, with types

    int[] prices in, int out. Can the array be empty? What is returned then? Can it be null?

  3. 3
    Constraints

    How big is n? Can values be negative? Duplicates? Already sorted? These decide the algorithm (see the Big-O lesson below).

  4. 4
    Two examples by hand

    One normal, one tricky. Work them out on paper. If you cannot do it by hand, you cannot code it.

  5. 5
    Edge cases

    Empty input, one element, all equal, already sorted, values big enough to overflow int (C# wraps silently unless you use checked, see Module 01).

C#Program.cs
// Restated: best profit from one buy then one later sell; 0 if prices only fall.
// Input: int[] prices (may be empty). Output: int >= 0.
Console.WriteLine(MaxProfit([7, 1, 5, 3, 6, 4])); // normal: buy at 1, sell at 6
Console.WriteLine(MaxProfit([7, 6, 4, 3, 1]));    // prices only fall
Console.WriteLine(MaxProfit([]));                 // empty
Console.WriteLine(MaxProfit([5]));                // one day

static int MaxProfit(int[] prices)
{
    int lowest = int.MaxValue, best = 0;
    foreach (int price in prices)
    {
        lowest = Math.Min(lowest, price);      // cheapest buy so far
        best = Math.Max(best, price - lowest); // what if I sell today?
    }
    return best;
}
Outputcompiled & run with real C#
5
0
0
0

The two comments at the top are the reading step. The four calls are the examples and edge cases from that step, written before the method, not bolted on after.

Your turn

Change the contract to "return the buy day and sell day as a tuple, or (-1, -1) if no profit is possible". Which of the four calls now needs a different expected answer?

02

Break it down and test with small cases

Break the problem into pieces you can test separately: a helper that checks one thing, a loop that applies it. Then test with the smallest inputs that could break it. In an interview, and in your own practice, a tiny Check local function is faster than setting up xUnit, and it shows the interviewer you verify your own code.

C#Program.cs
int passed = 0, failed = 0;

Check("", true);                          // empty
Check("a", true);                         // one character
Check("ab", false);                       // smallest false case
Check("Aba", true);                       // mixed case
Check("A man, a plan, a canal: Panama", true);
Check("race a car", false);
Check(".,", true);                        // only punctuation
Console.WriteLine($"{passed} passed, {failed} failed");

void Check(string input, bool expected)
{
    bool got = IsPalindrome(input);
    if (got == expected) passed++;
    else
    {
        failed++;
        Console.WriteLine($"FAIL '{input}': expected {expected}, got {got}");
    }
}

static bool IsPalindrome(string s)
{
    int i = 0, j = s.Length - 1;
    while (i < j)
    {
        char a = s[i], b = s[j];
        if (!char.IsLetterOrDigit(a)) { i++; continue; }
        if (!char.IsLetterOrDigit(b)) { j--; continue; }
        if (char.ToLowerInvariant(a) != char.ToLowerInvariant(b)) return false;
        i++;
        j--;
    }
    return true;
}
Outputcompiled & run with real C#
7 passed, 0 failed

Check is a non-static local function, so it can update passed and failed from the top-level code. IsPalindrome is static because it needs nothing from outside.

Your turn

Break IsPalindrome on purpose (drop the two ToLowerInvariant calls) and run it. Exactly two cases report FAIL. That is how a good small-case list pinpoints a bug.

The order to test in
Empty, one element, two elements, the example from the problem, then one case aimed at each branch of your code. Small inputs make a wrong answer obvious by eye.
03

Big-O in plain English

Big-O answers one question: if the input gets ten times bigger, how much slower does this get? O(n) gets ten times slower. O(n²) gets a hundred times slower. O(log n) barely notices. A C# program does very roughly 108 simple operations per second, which turns the constraints in a problem statement into a direct hint about which algorithm is expected.

Rules of thumb, not laws. They are good enough to rule out the wrong approach before you write it.
If n is up to…You can affordTypical approach
10 to 20O(2n) or O(n!)Backtracking: try every subset or ordering
~500O(n³)Three nested loops, small DP tables
~5,000O(n²)Two nested loops, 2-D DP
~106O(n log n)Sort first, a heap, binary search inside a loop
~108O(n)One pass: two pointers, sliding window, Dictionary
Anything largerO(log n) or O(1)Binary search on the answer, a formula
C#Program.cs
foreach (int n in new[] { 1_000, 10_000 })
{
    int[] a = Enumerable.Range(0, n).ToArray(); // no duplicates: the worst case
    Console.WriteLine($"n={n}  nested={NestedOps(a)}  set={SetOps(a)}");
}

// O(n^2): compare every pair
static long NestedOps(int[] a)
{
    long ops = 0;
    for (int i = 0; i < a.Length; i++)
        for (int j = i + 1; j < a.Length; j++)
        {
            ops++;
            if (a[i] == a[j]) return ops;
        }
    return ops;
}

// O(n): remember what we have seen
static long SetOps(int[] a)
{
    long ops = 0;
    var seen = new HashSet<int>();
    foreach (int x in a)
    {
        ops++;
        if (!seen.Add(x)) return ops; // Add returns false for a duplicate
    }
    return ops;
}
Outputcompiled & run with real C#
n=1000  nested=499500  set=1000
n=10000  nested=49995000  set=10000

Ten times the input: the nested version does a hundred times the work, the set version ten times. At n = 106 the nested version would need half a trillion comparisons.

Your turn

Add a third method that sorts a copy of the array and then compares neighbours. Count its operations as n for the neighbour pass. What is its Big-O, including the sort?

04

Pattern 1: two pointers

Signal: a sorted array (or a string) and a question about pairs, or "do it in place". Put one index at each end and move them towards each other based on a comparison. Each step rules out a whole row of candidate pairs, so an O(n²) "try every pair" becomes O(n) with O(1) extra memory.

C#Program.cs
int[] a = [1, 3, 4, 6, 8, 11];
Console.WriteLine(PairSum(a, 10));
Console.WriteLine(PairSum(a, 2));

// sorted input: indices of two numbers that add up to target, or (-1, -1)
static (int, int) PairSum(int[] a, int target)
{
    int i = 0, j = a.Length - 1;
    while (i < j)
    {
        int sum = a[i] + a[j];
        if (sum == target) return (i, j);
        if (sum < target) i++; // need bigger: move the left pointer up
        else j--;              // need smaller: move the right pointer down
    }
    return (-1, -1);
}
Outputcompiled & run with real C#
(2, 3)
(-1, -1)
Your turn

Write static int[] SortedSquares(int[] a) for a sorted array that may hold negatives: [-4, -1, 0, 3, 10] gives [0, 1, 9, 16, 100]. Fill the result from the back, each time taking the larger of Math.Abs(a[i]) and Math.Abs(a[j]).

VisualizePairSum([1, 3, 4, 6, 8, 11], 10)Step 1 / 11
int i = 0, j = a.Length - 1;
while (i < j)
{
int sum = a[i] + a[j];
if (sum == target) return (i, j);
if (sum < target) i++;
else j--;
}
Line 1

Pointers at both ends.

Variables now
i0
j5
All 11 steps as a table
StepLineWhat happenedVariables now
11Pointers at both ends.i = 0 j = 5
241 + 11 = 12, too big.sum = 12
37Nothing can pair with 11 any more (1 is the smallest partner), so drop it.j = 4
441 + 8 = 9, too small.sum = 9
56Nothing can pair with 1 (8 is now the largest partner), so drop it.i = 1
643 + 8 = 11, too big.sum = 11
77Drop 8.j = 3
843 + 6 = 9, too small.sum = 9
96Drop 3.i = 2
1044 + 6 = 10.sum = 10
115Found: indices 2 and 3, after 5 checks instead of up to 15 pairs.
05

Pattern 2: sliding window

Signal: "longest / shortest / best contiguous subarray or substring such that…". Grow a window by moving its right edge; when the window breaks the rule, shrink it from the left. Each index enters and leaves the window at most once, so the whole scan is O(n).

C#Program.cs
Console.WriteLine($"{LongestUnique("abcabcbb")} {LongestUnique("bbbb")} {LongestUnique("pwwkew")}");
Console.WriteLine(MaxSumK([2, 1, 5, 1, 3, 2], 3));

// length of the longest substring with no repeated character
static int LongestUnique(string s)
{
    var lastSeen = new Dictionary<char, int>();
    int best = 0, left = 0;
    for (int right = 0; right < s.Length; right++)
    {
        char c = s[right];
        if (lastSeen.TryGetValue(c, out int prev) && prev >= left)
            left = prev + 1; // jump the left edge past the repeat
        lastSeen[c] = right;
        best = Math.Max(best, right - left + 1);
    }
    return best;
}

// fixed-size window: biggest sum of any k consecutive numbers
static int MaxSumK(int[] a, int k)
{
    int sum = 0;
    for (int i = 0; i < k; i++) sum += a[i];
    int best = sum;
    for (int i = k; i < a.Length; i++)
    {
        sum += a[i] - a[i - k]; // slide: add the new, drop the old
        best = Math.Max(best, sum);
    }
    return best;
}
Outputcompiled & run with real C#
3 1 3
9

The check prev >= left matters: a character last seen before the window started is not a repeat inside it.

Your turn

Write static int MinLengthAtLeast(int[] a, int target): the shortest contiguous run of positive numbers whose sum is at least target (0 if none). Grow right, then shrink left while the sum still qualifies. [2, 3, 1, 2, 4, 3] with target 7 gives 2.

06

Pattern 3: Dictionary and HashSet lookups

Signal: "have I seen X before?", "count occurrences", "find the complement". Trade memory for time: store what you have seen in a Dictionary<TKey, TValue> or HashSet<T>, and each lookup is O(1) on average instead of another loop. This is the single most common interview pattern.

C#Program.cs
Console.WriteLine(TwoSum([3, 8, 2, 11, 7], 9));
foreach (var group in GroupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"]))
    Console.WriteLine(string.Join(", ", group));

// unsorted input: indices of two numbers adding to target (the classic "Two Sum")
static (int, int) TwoSum(int[] nums, int target)
{
    var indexOf = new Dictionary<int, int>();
    for (int i = 0; i < nums.Length; i++)
    {
        if (indexOf.TryGetValue(target - nums[i], out int j)) return (j, i);
        indexOf[nums[i]] = i;
    }
    return (-1, -1);
}

// group words that are anagrams of each other
static IEnumerable<List<string>> GroupAnagrams(string[] words)
{
    var groups = new SortedDictionary<string, List<string>>(StringComparer.Ordinal);
    foreach (string w in words)
    {
        string key = string.Concat(w.Order()); // "tea" -> "aet"
        if (!groups.TryGetValue(key, out var list)) groups[key] = list = [];
        list.Add(w);
    }
    return groups.Values;
}
Outputcompiled & run with real C#
(2, 4)
bat
eat, tea, ate
tan, nat

The sorted letters are the key: "eat", "tea" and "ate" all sort to "aet". A SortedDictionary with an ordinal comparer keeps the group order the same on every machine; a plain Dictionary does not promise any order.

Your turn

Write static char? FirstUnique(string s): count every character in one pass with a Dictionary<char, int>, then scan the string again for the first count of 1. "swiss" gives w; "aabb" gives null.

07

Pattern 4: stack

Signal: matching pairs, "the next greater / smaller element", undo, or evaluating expressions. (Bracket matching is in Module 13.) A monotonic stack keeps indices whose values are still waiting for an answer; when a bigger value arrives, it resolves everything smaller on top of the stack. Every index is pushed and popped once: O(n).

C#Program.cs
int[] temps = [73, 74, 75, 71, 69, 72, 76, 73];
Console.WriteLine(string.Join(", ", DaysUntilWarmer(temps)));
Console.WriteLine($"{Rpn("3 4 + 2 *")} {Rpn("10 3 -")}");

// for each day, how many days until a warmer temperature (0 if never)
static int[] DaysUntilWarmer(int[] temps)
{
    var answer = new int[temps.Length];
    var waiting = new Stack<int>(); // indices still waiting; coolest on top
    for (int i = 0; i < temps.Length; i++)
    {
        while (waiting.Count > 0 && temps[i] > temps[waiting.Peek()])
        {
            int day = waiting.Pop();
            answer[day] = i - day;
        }
        waiting.Push(i);
    }
    return answer;
}

// reverse Polish notation: "3 4 + 2 *" means (3 + 4) * 2
static int Rpn(string expr)
{
    var st = new Stack<int>();
    foreach (string tok in expr.Split(" "))
    {
        switch (tok)
        {
            case "+": st.Push(st.Pop() + st.Pop()); break;
            case "*": st.Push(st.Pop() * st.Pop()); break;
            case "-": { int b = st.Pop(), a = st.Pop(); st.Push(a - b); break; }
            default: st.Push(int.Parse(tok)); break;
        }
    }
    return st.Pop();
}
Outputcompiled & run with real C#
1, 1, 4, 2, 1, 1, 0, 0
14 7

For subtraction the order matters: the first Pop is the right-hand operand. Pop into named variables whenever the operator is not commutative.

Your turn

Write static int[] NextGreater(int[] a): for each element, the next value to its right that is larger, or -1. It is the same loop as DaysUntilWarmer, storing a[i] instead of i - day. [2, 1, 2, 4, 3] gives [4, 2, 4, -1, -1].

08

Pattern 5: recursion and backtracking

Signal: "all combinations", "all permutations", "every way to…", and a small n (roughly 20 or fewer). Build a candidate one choice at a time, recurse, then undo the choice (backtrack) and try the next one. The shape is always: choose, explore, un-choose. How recursion uses the call stack is in Module 13.

C#Program.cs
var subsets = new List<List<int>>();
Subsets([1, 2, 3], 0, [], subsets);
Console.WriteLine(string.Join(" ", subsets.Select(s => "[" + string.Join(",", s) + "]")));

var perms = new List<string>();
Permute("", "abc", perms);
Console.WriteLine(string.Join(" ", perms));

static void Subsets(int[] nums, int start, List<int> current, List<List<int>> output)
{
    output.Add([.. current]);                 // copy: current keeps changing
    for (int i = start; i < nums.Length; i++)
    {
        current.Add(nums[i]);                 // choose
        Subsets(nums, i + 1, current, output); // explore
        current.RemoveAt(current.Count - 1);  // un-choose
    }
}

static void Permute(string prefix, string rest, List<string> output)
{
    if (rest.Length == 0) { output.Add(prefix); return; }
    for (int i = 0; i < rest.Length; i++)
        Permute(prefix + rest[i], rest.Remove(i, 1), output);
}
Outputcompiled & run with real C#
[] [1] [1,2] [1,2,3] [1,3] [2] [2,3] [3]
abc acb bac bca cab cba

Writing output.Add(current) instead of a copy is the classic bug: every entry would be the same List<int> object, emptied by the end, and the program would print eight [].

Your turn

Add a target: print only the subsets of [2, 3, 5, 7] that sum to 10. Pass the running sum down, and return early once it passes 10 so hopeless branches are never explored.

09

Pattern 6: sort first

Signal: intervals, "closest", meeting rooms, duplicates, or anything where order would make the answer obvious. Sorting costs O(n log n) once and often turns the rest into a single O(n) pass.

C#Program.cs
List<(int Start, int End)> meetings = [(8, 10), (1, 3), (2, 6), (15, 18), (17, 20)];
Console.WriteLine(string.Join(" ", Merge(meetings)));

static List<(int Start, int End)> Merge(List<(int Start, int End)> intervals)
{
    var merged = new List<(int Start, int End)>();
    foreach (var iv in intervals.OrderBy(iv => iv.Start))
    {
        if (merged.Count > 0 && iv.Start <= merged[^1].End)
            merged[^1] = (merged[^1].Start, Math.Max(merged[^1].End, iv.End)); // overlap: extend
        else
            merged.Add(iv); // gap: start a new interval
    }
    return merged;
}
Outputcompiled & run with real C#
(1, 6) (8, 10) (15, 20)

Unsorted, you would compare every interval with every other one. Sorted by start, an interval can only overlap the one just before it. The tuple is replaced whole because merged[^1].End = … will not compile: the list indexer returns a copy of the struct (error CS1612).

Your turn

Write static bool CanAttendAll(List<(int Start, int End)> meetings): sort by start, then return false as soon as a meeting starts before the previous one ends. The list above gives False; [(1, 2), (3, 4)] gives True.

10

Pattern 7: BFS and DFS on a grid

Signal: a grid, a maze, a network, "connected", "reachable", "fewest steps". Treat each cell as a node with up to four neighbours. DFS answers "how many separate regions?"; BFS answers "what is the fewest number of moves?". Module 13 ran both on an explicit graph of named nodes (Graphs: BFS, DFS); a grid is the same idea with the edges computed from coordinates.

C#Program.cs
(int Dr, int Dc)[] dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)];

char[][] map =
[
    "##..#".ToCharArray(),
    "#...#".ToCharArray(),
    "..#..".ToCharArray(),
    "....#".ToCharArray(),
];
Console.WriteLine($"islands: {CountIslands(map)}");
Console.WriteLine($"steps: {ShortestPath(["..#.", ".#..", "....", "#.#."])}");

int CountIslands(char[][] g)
{
    int count = 0;
    for (int r = 0; r < g.Length; r++)
        for (int c = 0; c < g[0].Length; c++)
            if (g[r][c] == '#') { count++; Sink(g, r, c); }
    return count;
}

void Sink(char[][] g, int r, int c) // DFS: turn a whole island into water
{
    if (r < 0 || c < 0 || r >= g.Length || c >= g[0].Length || g[r][c] != '#') return;
    g[r][c] = '.';
    foreach (var (dr, dc) in dirs) Sink(g, r + dr, c + dc);
}

int ShortestPath(string[] maze) // BFS from top-left to bottom-right, -1 if unreachable
{
    int rows = maze.Length, cols = maze[0].Length;
    var dist = new int[rows, cols];
    for (int r = 0; r < rows; r++)
        for (int c = 0; c < cols; c++) dist[r, c] = -1;
    var queue = new Queue<(int R, int C)>();
    dist[0, 0] = 0;
    queue.Enqueue((0, 0));
    while (queue.Count > 0)
    {
        var (r, c) = queue.Dequeue();
        foreach (var (dr, dc) in dirs)
        {
            int nr = r + dr, nc = c + dc;
            if (nr >= 0 && nc >= 0 && nr < rows && nc < cols && maze[nr][nc] == '.' && dist[nr, nc] == -1)
            {
                dist[nr, nc] = dist[r, c] + 1;
                queue.Enqueue((nr, nc));
            }
        }
    }
    return dist[rows - 1, cols - 1];
}
Outputcompiled & run with real C#
islands: 4
steps: 6

"Sinking" visited land to . is the visited set, stored in the grid itself. On a very large grid, recursive DFS can overflow the stack (a crash .NET cannot catch); switch to an explicit Stack<(int, int)> then.

Your turn

Change CountIslands to return the size of the largest island instead of the count: make Sink return how many cells it turned to water. The map above gives 3.

11

Pattern 8: DP-lite

Signal: "how many ways", "minimum cost", "maximum value", where the answer at position i depends on answers just before it. Write the recurrence in words first ("best up to house i = the better of skipping it, or robbing it plus the best up to i - 2"), then fill an array or keep two variables. Memoisation versus tabulation is covered in Module 13; these are the small, one-pass DPs that turn up most in interviews.

C#Program.cs
Console.WriteLine($"paths 3x3 = {UniquePaths(3, 3)}, 3x7 = {UniquePaths(3, 7)}");
Console.WriteLine($"rob = {Rob([2, 7, 9, 3, 1])}");
Console.WriteLine($"max subarray = {MaxSubarray([-2, 1, -3, 4, -1, 2, 1, -5, 4])}");

// a robot moves only right or down: how many routes from top-left to bottom-right?
static long UniquePaths(int rows, int cols)
{
    var row = new long[cols];
    Array.Fill(row, 1L);            // top row: exactly one way to reach each cell
    for (int r = 1; r < rows; r++)
        for (int c = 1; c < cols; c++)
            row[c] += row[c - 1];   // from above (old row[c]) + from the left
    return row[cols - 1];
}

// most money from houses in a row without robbing two neighbours
static int Rob(int[] houses)
{
    int skip = 0, take = 0;         // best so far without / with the previous house
    foreach (int money in houses)
    {
        int newTake = skip + money;
        skip = Math.Max(skip, take);
        take = newTake;
    }
    return Math.Max(skip, take);
}

// largest sum of a contiguous subarray (Kadane)
static int MaxSubarray(int[] a)
{
    int best = a[0], endingHere = a[0];
    for (int i = 1; i < a.Length; i++)
    {
        endingHere = Math.Max(a[i], endingHere + a[i]); // extend, or start fresh here
        best = Math.Max(best, endingHere);
    }
    return best;
}
Outputcompiled & run with real C#
paths 3x3 = 6, 3x7 = 28
rob = 12
max subarray = 6

UniquePaths needs only one row of the 2-D table, because each cell reads the cell above (still in row[c]) and the cell to its left (just updated). O(rows × cols) time, O(cols) memory.

Your turn

Write static int MinCostClimb(int[] cost): you may start on step 0 or 1, climb 1 or 2 steps at a time, and pay cost[i] for each step you land on; return the cheapest way past the top. [10, 15, 20] gives 15, and [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] gives 6.

12

Choosing the pattern

The problem says…Try firstC# tool
sorted array, pair or triplet with a sum, in placeTwo pointerstwo int indexes
longest / shortest contiguous substring or subarraySliding windowDictionary<char, int> for the window
seen before, count, duplicate, complementHash lookupDictionary / HashSet
brackets, next greater, undo, expressionStackStack<T>
all combinations / permutations, n ≤ 20Backtrackingrecursion + a List<T> you add to and remove from
intervals, closest, meeting roomsSort firstOrderBy / Array.Sort
grid, maze, network, connected, fewest stepsBFS (shortest) / DFS (regions)Queue<T> / recursion or Stack<T>
how many ways, min cost, max value, depends on previousDPan array or two variables
top k, k-th largest, merge k sortedHeap (Module 13)PriorityQueue<TElement, TPriority>
sorted data and "smallest X such that…"Binary search (Module 13)Array.BinarySearch or by hand
Talk while you solve
In a real interview, say the brute force first ("try every pair, O(n²)"), then name the pattern that improves it and why. An interviewer can give credit for a correct plan even if the code runs out of time; silence gives them nothing to grade. Module 15 walks through a full coding round this way.
Brute force
The simplest correct solution, usually trying every possibility. State it first, then improve it.
Two pointers
Two indexes moving through an array (often from both ends) to avoid a nested loop.
Sliding window
A contiguous range [left, right] that grows on the right and shrinks on the left, touching each element at most twice.
Monotonic stack
A stack whose values stay in increasing or decreasing order; used for next-greater and next-smaller problems.
Backtracking
Recursive search that makes a choice, explores, then undoes the choice before trying the next.
Recurrence
A formula for an answer in terms of answers to smaller inputs; the heart of every DP solution.
Edge case
An input at the boundary of what is allowed: empty, one element, maximum size, negative, overflow.
Quick check

The constraints say n ≤ 100,000. Which approach is most likely expected?

Quick check

"Find the length of the longest substring with at most two distinct characters." Which pattern fits?

Frequently asked questions

How do I get better at solving coding problems in C#?
Practise by pattern, not at random: do three to five problems per pattern (two pointers, sliding window, hash lookup, stack, backtracking, sorting, BFS/DFS, DP) until you recognise the signal in the problem statement. Always write the brute force first, test with small cases, and state the Big-O out loud.
Which C# collections do I need for coding interviews?
List, Dictionary, HashSet, Stack, Queue, PriorityQueue and SortedDictionary or SortedSet cover nearly every problem. Know Array.Sort, OrderBy/ThenBy, Array.Fill, TryGetValue and GetValueOrDefault as well.
Can I use LINQ in a coding interview?
Usually yes, and it reads well for sorting and grouping. Be ready to state the cost of each call (OrderBy is O(n log n), Contains on a List is O(n)) and to write the loop yourself if the interviewer asks what LINQ is doing underneath.

Finish the C# handbook, then get hired

Sit the exam for your certificate, run your resume through the ATS checker, and see the jobs that ask for exactly this.

Check my resume
Found this course useful? Share it.
ShareXLinkedIn

Comments

0

Join the conversation. Sign in to leave a comment — we'd love to hear your thoughts.