BuildQuill
Problem collection 50/50 compiler verified

50 C# coding problems with solutions

Move from loops and strings to stacks, graphs, recursion, and dynamic programming. Each problem includes a strategy, complexity analysis, a complete runnable program, and its exact verified output.

Complete programs
50
Beginner
25
Intermediate
25
Run any solution
1 click
Jump to a problem +

Run what you read

Every code block is a complete program compatible with BuildQuill’s compiler. Select Run in compiler to transfer and execute it immediately.

#01Beginnerloopsconditions

FizzBuzz

The task

Problem

Print the numbers 1 through 20. Replace multiples of 3 with Fizz, multiples of 5 with Buzz, and multiples of both with FizzBuzz.

How to think about it

Approach

Check divisibility by 15 first so a number divisible by both 3 and 5 is not handled by an earlier branch.

ComplexityTime O(n), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static void Main()
    {
        for (int number = 1; number <= 20; number++)
        {
            if (number % 15 == 0) Console.WriteLine("FizzBuzz");
            else if (number % 3 == 0) Console.WriteLine("Fizz");
            else if (number % 5 == 0) Console.WriteLine("Buzz");
            else Console.WriteLine(number);
        }
    }
}

Verified output

1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Back to top ↑
#02Beginneriterationstate

Fibonacci sequence

The task

Problem

Generate the first 10 Fibonacci numbers, starting with 0 and 1.

How to think about it

Approach

Keep only the previous two values. Print the current value, then advance both variables together.

ComplexityTime O(n), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static void Main()
    {
        int previous = 0;
        int current = 1;

        for (int i = 0; i < 10; i++)
        {
            Console.Write(previous + (i == 9 ? "" : " "));
            int next = previous + current;
            previous = current;
            current = next;
        }
    }
}

Verified output

0 1 1 2 3 5 8 13 21 34
Back to top ↑
#03Beginnerloopsvalidation

Calculate a factorial

The task

Problem

Calculate n! for an integer from 0 through 20. For example, 5! equals 5 × 4 × 3 × 2 × 1.

How to think about it

Approach

Start the product at 1 and multiply by every integer from 2 through n. Restrict the input to 0 through 20 because 21! exceeds the range of long.

ComplexityTime O(n), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static long Factorial(int number)
    {
        if (number < 0 || number > 20)
            throw new ArgumentOutOfRangeException("number");

        long result = 1;
        for (int factor = 2; factor <= number; factor++) result *= factor;
        return result;
    }

    static void Main()
    {
        Console.WriteLine(Factorial(5));
    }
}

Verified output

120
Back to top ↑
#04Beginnerstringstwo pointers

Palindrome checker

The task

Problem

Determine whether a phrase reads the same forward and backward while ignoring spaces, punctuation, and letter case.

How to think about it

Approach

Move pointers inward from both ends. Skip non-alphanumeric characters and compare the remaining characters case-insensitively.

ComplexityTime O(n), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static bool IsPalindrome(string text)
    {
        int left = 0;
        int right = text.Length - 1;

        while (left < right)
        {
            if (!char.IsLetterOrDigit(text[left])) { left++; continue; }
            if (!char.IsLetterOrDigit(text[right])) { right--; continue; }
            if (char.ToLowerInvariant(text[left]) != char.ToLowerInvariant(text[right])) return false;
            left++;
            right--;
        }
        return true;
    }

    static void Main()
    {
        Console.WriteLine(IsPalindrome("Never odd or even"));
    }
}

Verified output

True
Back to top ↑
#05Beginnermathearly return

Prime number test

The task

Problem

Check whether an integer is prime: greater than 1 and divisible only by 1 and itself.

How to think about it

Approach

After handling values below 2, test possible divisors only up to the square root. Any larger factor would have a smaller paired factor.

ComplexityTime O(√n), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static bool IsPrime(int number)
    {
        if (number < 2) return false;
        if (number == 2) return true;
        if (number % 2 == 0) return false;

        for (int divisor = 3; divisor <= number / divisor; divisor += 2)
            if (number % divisor == 0) return false;
        return true;
    }

    static void Main()
    {
        Console.WriteLine(IsPrime(29));
    }
}

Verified output

True
Back to top ↑
#06Beginnerarraystwo pointers

Reverse a string

The task

Problem

Reverse the characters in a string without calling Array.Reverse.

How to think about it

Approach

Copy the immutable string into a character array, then swap the first and last characters while moving toward the center.

ComplexityTime O(n), space O(n) for the character array.

Complete C# solution

C#
using System;

class Program
{
    static string Reverse(string text)
    {
        char[] characters = text.ToCharArray();
        int left = 0;
        int right = characters.Length - 1;

        while (left < right)
        {
            char temporary = characters[left];
            characters[left] = characters[right];
            characters[right] = temporary;
            left++;
            right--;
        }
        return new string(characters);
    }

    static void Main()
    {
        Console.WriteLine(Reverse("BuildQuill"));
    }
}

Verified output

lliuQdliuB
Back to top ↑
#07Beginnerdictionarystrings

Anagram checker

The task

Problem

Check whether two phrases contain the same letters in a different order, ignoring spaces, punctuation, and case.

How to think about it

Approach

Build a frequency table by adding counts from the first phrase and subtracting counts from the second. Every final count must be zero.

ComplexityTime O(n + m), space O(k), where k is the number of distinct characters.

Complete C# solution

C#
using System;
using System.Collections.Generic;

class Program
{
    static bool AreAnagrams(string first, string second)
    {
        var counts = new Dictionary<char, int>();

        foreach (char raw in first)
        {
            if (!char.IsLetterOrDigit(raw)) continue;
            char key = char.ToLowerInvariant(raw);
            int count;
            counts.TryGetValue(key, out count);
            counts[key] = count + 1;
        }

        foreach (char raw in second)
        {
            if (!char.IsLetterOrDigit(raw)) continue;
            char key = char.ToLowerInvariant(raw);
            int count;
            counts.TryGetValue(key, out count);
            counts[key] = count - 1;
        }

        foreach (int count in counts.Values)
            if (count != 0) return false;
        return true;
    }

    static void Main()
    {
        Console.WriteLine(AreAnagrams("Dormitory", "Dirty room"));
    }
}

Verified output

True
Back to top ↑
#08Beginnerarrayslinear scan

Find the largest array value

The task

Problem

Find the largest number in a non-empty integer array without sorting it.

How to think about it

Approach

Treat the first item as the current maximum, then replace it whenever a larger item appears.

ComplexityTime O(n), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static int FindLargest(int[] numbers)
    {
        if (numbers.Length == 0) throw new ArgumentException("Array cannot be empty.");
        int largest = numbers[0];
        foreach (int number in numbers)
            if (number > largest) largest = number;
        return largest;
    }

    static void Main()
    {
        Console.WriteLine(FindLargest(new[] { 12, 7, 31, 18, 4 }));
    }
}

Verified output

31
Back to top ↑
#10Beginnersortingnested loops

Bubble sort

The task

Problem

Sort an integer array in ascending order using bubble sort.

How to think about it

Approach

Repeatedly swap adjacent out-of-order values. After each pass, the largest unsorted value has moved to its final position.

ComplexityTime O(n²), space O(1). The early-exit flag makes already sorted input O(n).

Complete C# solution

C#
using System;

class Program
{
    static void BubbleSort(int[] numbers)
    {
        for (int end = numbers.Length - 1; end > 0; end--)
        {
            bool swapped = false;
            for (int i = 0; i < end; i++)
            {
                if (numbers[i] <= numbers[i + 1]) continue;
                int temporary = numbers[i];
                numbers[i] = numbers[i + 1];
                numbers[i + 1] = temporary;
                swapped = true;
            }
            if (!swapped) return;
        }
    }

    static void Main()
    {
        int[] values = { 5, 1, 4, 2, 8 };
        BubbleSort(values);
        Console.WriteLine(string.Join(" ", values));
    }
}

Verified output

1 2 4 5 8
Back to top ↑
#11Beginnermoduloconditions

Determine whether a number is even or odd

The task

Problem

Determine whether an integer is even or odd, including when the value is negative.

How to think about it

Approach

An integer is even when division by 2 leaves a remainder of zero. Every other integer is odd.

ComplexityTime O(1), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static string EvenOrOdd(int number)
    {
        return number % 2 == 0 ? "Even" : "Odd";
    }

    static void Main()
    {
        Console.WriteLine(EvenOrOdd(-7));
    }
}

Verified output

Odd
Back to top ↑
#12Beginnerarraysaccumulator

Sum all values in an array

The task

Problem

Calculate the sum of all integers in an array without using LINQ.

How to think about it

Approach

Start an accumulator at zero and add each value during one pass through the array. Use long for the running total to support sums outside the int range.

ComplexityTime O(n), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static long Sum(int[] numbers)
    {
        long total = 0;
        foreach (int number in numbers) total += number;
        return total;
    }

    static void Main()
    {
        Console.WriteLine(Sum(new[] { 4, -2, 7, 1 }));
    }
}

Verified output

10
Back to top ↑
#13Beginnerstringscharacter matching

Count vowels in a string

The task

Problem

Count the English vowels in a string without treating uppercase and lowercase letters differently.

How to think about it

Approach

Normalize each character to lowercase and check whether it appears in the fixed set of vowels.

ComplexityTime O(n), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static int CountVowels(string text)
    {
        const string vowels = "aeiou";
        int count = 0;
        foreach (char symbol in text)
            if (vowels.IndexOf(char.ToLowerInvariant(symbol)) >= 0) count++;
        return count;
    }

    static void Main()
    {
        Console.WriteLine(CountVowels("Build useful tools"));
    }
}

Verified output

7
Back to top ↑
#14Beginnermoduloloops

Sum the digits of an integer

The task

Problem

Add the decimal digits of an integer. Ignore the sign when the value is negative.

How to think about it

Approach

Convert the value to a non-negative long, repeatedly take the final digit with modulo 10, then remove that digit with integer division.

ComplexityTime O(d), space O(1), where d is the number of digits.

Complete C# solution

C#
using System;

class Program
{
    static int SumDigits(int number)
    {
        long remaining = Math.Abs((long)number);
        int total = 0;
        do
        {
            total += (int)(remaining % 10);
            remaining /= 10;
        } while (remaining > 0);
        return total;
    }

    static void Main()
    {
        Console.WriteLine(SumDigits(-4827));
    }
}

Verified output

21
Back to top ↑
#15Beginnerloopsformatted output

Print a multiplication table

The task

Problem

Print the first 10 multiples of a given integer in equation form.

How to think about it

Approach

Loop from 1 through 10 and multiply the input by the current counter for each line.

ComplexityTime O(1) for 10 fixed rows, space O(1).

Complete C# solution

C#
using System;

class Program
{
    static void Main()
    {
        int number = 7;
        for (int multiplier = 1; multiplier <= 10; multiplier++)
            Console.WriteLine(number + " x " + multiplier + " = " + number * multiplier);
    }
}

Verified output

7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
7 x 10 = 70
Back to top ↑
#16Beginnerboolean logicconditions

Leap year checker

The task

Problem

Determine whether a year is a leap year under the Gregorian calendar rules.

How to think about it

Approach

A leap year is divisible by 400, or it is divisible by 4 but not by 100. Test the century exception explicitly.

ComplexityTime O(1), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static bool IsLeapYear(int year)
    {
        return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
    }

    static void Main()
    {
        Console.WriteLine("2024: " + IsLeapYear(2024));
        Console.WriteLine("1900: " + IsLeapYear(1900));
    }
}

Verified output

2024: True
1900: False
Back to top ↑
#17BeginnerEuclidean algorithmmodulo

Greatest common divisor

The task

Problem

Find the greatest common divisor of two integers, treating negative inputs as their absolute values.

How to think about it

Approach

Use Euclid's algorithm: replace the pair with the second value and the remainder until the remainder becomes zero.

ComplexityTime O(log min(a, b)), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static long GreatestCommonDivisor(int first, int second)
    {
        long a = Math.Abs((long)first);
        long b = Math.Abs((long)second);
        while (b != 0)
        {
            long remainder = a % b;
            a = b;
            b = remainder;
        }
        return a;
    }

    static void Main()
    {
        Console.WriteLine(GreatestCommonDivisor(84, 30));
    }
}

Verified output

6
Back to top ↑
#18Beginnernumber systemsdivision

Convert decimal to binary

The task

Problem

Convert a non-negative decimal integer to its binary representation without using Convert.ToString.

How to think about it

Approach

Repeatedly divide by 2 and write each remainder from the end of a buffer toward the front. Handle zero as a special case.

ComplexityTime O(log n), space O(log n).

Complete C# solution

C#
using System;

class Program
{
    static string ToBinary(int number)
    {
        if (number < 0) throw new ArgumentOutOfRangeException("number");
        if (number == 0) return "0";

        char[] bits = new char[32];
        int write = bits.Length;
        while (number > 0)
        {
            bits[--write] = (char)('0' + number % 2);
            number /= 2;
        }
        return new string(bits, write, bits.Length - write);
    }

    static void Main()
    {
        Console.WriteLine(ToBinary(42));
    }
}

Verified output

101010
Back to top ↑
#20Beginnerarraysstate tracking

Find the second-largest distinct value

The task

Problem

Find the second-largest distinct integer in an array without sorting it. Reject arrays that do not contain two distinct values.

How to think about it

Approach

Track the largest and second-largest distinct values during one scan. Boolean flags avoid unsafe sentinel values for arrays containing int.MinValue.

ComplexityTime O(n), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static int SecondLargest(int[] numbers)
    {
        int largest = 0, second = 0;
        bool hasLargest = false, hasSecond = false;

        foreach (int number in numbers)
        {
            if (!hasLargest || number > largest)
            {
                if (hasLargest) { second = largest; hasSecond = true; }
                largest = number;
                hasLargest = true;
            }
            else if (number != largest && (!hasSecond || number > second))
            {
                second = number;
                hasSecond = true;
            }
        }

        if (!hasSecond) throw new ArgumentException("Two distinct values are required.");
        return second;
    }

    static void Main()
    {
        Console.WriteLine(SecondLargest(new[] { 8, 3, 8, 6, 2 }));
    }
}

Verified output

6
Back to top ↑
#21Beginnersortingnested loops

Selection sort

The task

Problem

Sort an integer array in ascending order using selection sort.

How to think about it

Approach

For each position, find the smallest value in the remaining unsorted suffix and swap it into place.

ComplexityTime O(n^2), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static void SelectionSort(int[] numbers)
    {
        for (int start = 0; start < numbers.Length - 1; start++)
        {
            int smallest = start;
            for (int i = start + 1; i < numbers.Length; i++)
                if (numbers[i] < numbers[smallest]) smallest = i;

            int temporary = numbers[start];
            numbers[start] = numbers[smallest];
            numbers[smallest] = temporary;
        }
    }

    static void Main()
    {
        int[] values = { 9, 5, 1, 7, 3 };
        SelectionSort(values);
        Console.WriteLine(string.Join(" ", values));
    }
}

Verified output

1 3 5 7 9
Back to top ↑
#22Beginnersortingarray shifting

Insertion sort

The task

Problem

Sort an integer array in ascending order using insertion sort.

How to think about it

Approach

Grow a sorted prefix. Remove the next value, shift larger prefix values one position right, and insert the value into the gap.

ComplexityTime O(n^2), space O(1). Nearly sorted input approaches O(n) time.

Complete C# solution

C#
using System;

class Program
{
    static void InsertionSort(int[] numbers)
    {
        for (int i = 1; i < numbers.Length; i++)
        {
            int value = numbers[i];
            int position = i - 1;
            while (position >= 0 && numbers[position] > value)
            {
                numbers[position + 1] = numbers[position];
                position--;
            }
            numbers[position + 1] = value;
        }
    }

    static void Main()
    {
        int[] values = { 5, 2, 4, 6, 1, 3 };
        InsertionSort(values);
        Console.WriteLine(string.Join(" ", values));
    }
}

Verified output

1 2 3 4 5 6
Back to top ↑
#23Beginnerarithmeticmethods

Convert Celsius to Fahrenheit

The task

Problem

Convert a temperature from degrees Celsius to degrees Fahrenheit.

How to think about it

Approach

Multiply the Celsius value by 9/5 using floating-point division, then add 32.

ComplexityTime O(1), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static double CelsiusToFahrenheit(double celsius)
    {
        return celsius * 9.0 / 5.0 + 32.0;
    }

    static void Main()
    {
        Console.WriteLine(CelsiusToFahrenheit(25));
    }
}

Verified output

77
Back to top ↑
#24Beginnerstringscounting

Count character occurrences

The task

Problem

Count how many times a target character occurs in a string while ignoring letter case.

How to think about it

Approach

Normalize the target once, normalize each character during a single pass, and increment the count for each match.

ComplexityTime O(n), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static int CountOccurrences(string text, char target)
    {
        char normalizedTarget = char.ToUpperInvariant(target);
        int count = 0;
        foreach (char symbol in text)
            if (char.ToUpperInvariant(symbol) == normalizedTarget) count++;
        return count;
    }

    static void Main()
    {
        Console.WriteLine(CountOccurrences("Mississippi", 's'));
    }
}

Verified output

4
Back to top ↑
#25BeginnerstringsStringBuilder

Remove whitespace from a string

The task

Problem

Remove spaces, tabs, line breaks, and other whitespace characters from a string.

How to think about it

Approach

Append only non-whitespace characters to a StringBuilder so the result is built efficiently in one pass.

ComplexityTime O(n), space O(n).

Complete C# solution

C#
using System;
using System.Text;

class Program
{
    static string RemoveWhitespace(string text)
    {
        var result = new StringBuilder();
        foreach (char symbol in text)
            if (!char.IsWhiteSpace(symbol)) result.Append(symbol);
        return result.ToString();
    }

    static void Main()
    {
        Console.WriteLine(RemoveWhitespace(" C#\t is\n fun "));
    }
}

Verified output

C#isfun
Back to top ↑
#26Intermediatedictionarylookup

Two Sum

The task

Problem

Given an integer array and target, return the indexes of two different values whose sum equals the target.

How to think about it

Approach

As each value is visited, look for its required complement among previously seen values. Store the current value only after checking it.

ComplexityAverage time O(n), space O(n).

Complete C# solution

C#
using System;
using System.Collections.Generic;

class Program
{
    static int[] TwoSum(int[] numbers, int target)
    {
        var seen = new Dictionary<int, int>();
        for (int i = 0; i < numbers.Length; i++)
        {
            int complement = target - numbers[i];
            int otherIndex;
            if (seen.TryGetValue(complement, out otherIndex)) return new[] { otherIndex, i };
            seen[numbers[i]] = i;
        }
        throw new ArgumentException("No pair adds to the target.");
    }

    static void Main()
    {
        int[] result = TwoSum(new[] { 2, 7, 11, 15 }, 9);
        Console.WriteLine("(" + result[0] + ", " + result[1] + ")");
    }
}

Verified output

(0, 1)
Back to top ↑
#27Intermediatestackparsing

Balanced brackets

The task

Problem

Check whether every opening parenthesis, square bracket, and brace is closed in the correct order.

How to think about it

Approach

Push opening symbols onto a stack. Each closing symbol must match the most recent opening symbol, and the stack must be empty at the end.

ComplexityTime O(n), space O(n).

Complete C# solution

C#
using System;
using System.Collections.Generic;

class Program
{
    static bool IsBalanced(string text)
    {
        var expected = new Stack<char>();
        foreach (char symbol in text)
        {
            if (symbol == '(') expected.Push(')');
            else if (symbol == '[') expected.Push(']');
            else if (symbol == '{') expected.Push('}');
            else if (symbol == ')' || symbol == ']' || symbol == '}')
            {
                if (expected.Count == 0 || expected.Pop() != symbol) return false;
            }
        }
        return expected.Count == 0;
    }

    static void Main()
    {
        Console.WriteLine(IsBalanced("{[()]}") );
    }
}

Verified output

True
Back to top ↑
#28Intermediatetwo pointersarrays

Merge two sorted arrays

The task

Problem

Combine two sorted integer arrays into one sorted array without sorting the result afterward.

How to think about it

Approach

Compare the next unused item in each array, append the smaller one, then copy any remaining tail.

ComplexityTime O(n + m), space O(n + m) for the result.

Complete C# solution

C#
using System;

class Program
{
    static int[] Merge(int[] first, int[] second)
    {
        int[] result = new int[first.Length + second.Length];
        int i = 0, j = 0, write = 0;

        while (i < first.Length && j < second.Length)
            result[write++] = first[i] <= second[j] ? first[i++] : second[j++];
        while (i < first.Length) result[write++] = first[i++];
        while (j < second.Length) result[write++] = second[j++];
        return result;
    }

    static void Main()
    {
        Console.WriteLine(string.Join(" ", Merge(new[] { 1, 4, 7 }, new[] { 2, 3, 8 })));
    }
}

Verified output

1 2 3 4 7 8
Back to top ↑
#29Intermediatehash setstable order

Remove duplicate values

The task

Problem

Remove duplicate integers from an array while keeping the first occurrence of each value in its original order.

How to think about it

Approach

A HashSet records which values have appeared. Append a value to the result only when Add reports that it is new.

ComplexityAverage time O(n), space O(n).

Complete C# solution

C#
using System;
using System.Collections.Generic;

class Program
{
    static int[] DistinctInOrder(int[] numbers)
    {
        var seen = new HashSet<int>();
        var result = new List<int>();
        foreach (int number in numbers)
            if (seen.Add(number)) result.Add(number);
        return result.ToArray();
    }

    static void Main()
    {
        Console.WriteLine(string.Join(" ", DistinctInOrder(new[] { 4, 2, 4, 1, 2, 3 })));
    }
}

Verified output

4 2 1 3
Back to top ↑
#30Intermediatedictionarytext processing

Word frequency counter

The task

Problem

Count how often each word appears in a sentence, ignoring punctuation and letter case.

How to think about it

Approach

Extract word-like sequences with a regular expression, normalize them to lowercase, and increment their dictionary counts.

ComplexityTime O(n), space O(k), where k is the number of distinct words.

Complete C# solution

C#
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

class Program
{
    static Dictionary<string, int> CountWords(string text)
    {
        var counts = new Dictionary<string, int>();
        foreach (Match match in Regex.Matches(text.ToLowerInvariant(), @"[a-z0-9']+"))
        {
            int count;
            counts.TryGetValue(match.Value, out count);
            counts[match.Value] = count + 1;
        }
        return counts;
    }

    static void Main()
    {
        foreach (var pair in CountWords("Code, test, code, learn."))
            Console.WriteLine(pair.Key + ": " + pair.Value);
    }
}

Verified output

code: 2
test: 1
learn: 1
Back to top ↑
#31IntermediateXORarrays

Find the missing number

The task

Problem

An array contains distinct values from 0 through n with one value missing. Find the missing value.

How to think about it

Approach

XOR every expected index and every actual value. Equal values cancel, leaving only the missing number without risking arithmetic overflow.

ComplexityTime O(n), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static int FindMissing(int[] numbers)
    {
        int missing = numbers.Length;
        for (int i = 0; i < numbers.Length; i++) missing ^= i ^ numbers[i];
        return missing;
    }

    static void Main()
    {
        Console.WriteLine(FindMissing(new[] { 3, 0, 1 }));
    }
}

Verified output

2
Back to top ↑
#32Intermediaterecursiondivide and conquer

Tower of Hanoi

The task

Problem

Move three disks from peg A to peg C using peg B, moving one disk at a time and never placing a larger disk on a smaller one.

How to think about it

Approach

Move n−1 disks to the spare peg, move the largest disk to the destination, then move the n−1 disks onto it.

ComplexityTime O(2ⁿ), call-stack space O(n).

Complete C# solution

C#
using System;

class Program
{
    static void MoveDisks(int count, char source, char spare, char destination)
    {
        if (count == 0) return;
        MoveDisks(count - 1, source, destination, spare);
        Console.WriteLine("Move disk " + count + " from " + source + " to " + destination);
        MoveDisks(count - 1, spare, source, destination);
    }

    static void Main()
    {
        MoveDisks(3, 'A', 'B', 'C');
    }
}

Verified output

Move disk 1 from A to C
Move disk 2 from A to B
Move disk 1 from C to B
Move disk 3 from A to C
Move disk 1 from B to A
Move disk 2 from B to C
Move disk 1 from A to C
Back to top ↑
#33Intermediatelinked listreferences

Reverse a linked list

The task

Problem

Reverse a singly linked list in place and return its new head.

How to think about it

Approach

Walk through the list while redirecting each node's Next reference to the previous node. Save the original Next before changing it.

ComplexityTime O(n), space O(1).

Complete C# solution

C#
using System;
using System.Collections.Generic;

class Program
{
    class Node
    {
        public int Value { get; private set; }
        public Node Next { get; set; }

        public Node(int value, Node next = null)
        {
            Value = value;
            Next = next;
        }
    }

    static Node Reverse(Node current)
    {
        Node previous = null;
        while (current != null)
        {
            Node next = current.Next;
            current.Next = previous;
            previous = current;
            current = next;
        }
        return previous;
    }

    static void Main()
    {
        Node head = new Node(1, new Node(2, new Node(3)));
        var values = new List<int>();
        for (Node node = Reverse(head); node != null; node = node.Next) values.Add(node.Value);
        Console.WriteLine(string.Join(" ", values));
    }
}

Verified output

3 2 1
Back to top ↑
#34IntermediategraphqueueBFS

Shortest path with breadth-first search

The task

Problem

Find the fewest edges between two vertices in an unweighted graph.

How to think about it

Approach

Breadth-first search visits vertices one distance layer at a time. Record each vertex when it is enqueued so cycles cannot add it repeatedly.

ComplexityTime O(V + E), space O(V).

Complete C# solution

C#
using System;
using System.Collections.Generic;

class Program
{
    static int ShortestDistance(Dictionary<int, int[]> graph, int start, int target)
    {
        var queue = new Queue<int>();
        var distances = new Dictionary<int, int>();
        queue.Enqueue(start);
        distances[start] = 0;

        while (queue.Count > 0)
        {
            int current = queue.Dequeue();
            if (current == target) return distances[current];
            foreach (int neighbor in graph[current])
            {
                if (distances.ContainsKey(neighbor)) continue;
                distances[neighbor] = distances[current] + 1;
                queue.Enqueue(neighbor);
            }
        }
        return -1;
    }

    static void Main()
    {
        var graph = new Dictionary<int, int[]>
        {
            { 1, new[] { 2, 3 } }, { 2, new[] { 1, 4 } },
            { 3, new[] { 1, 4 } }, { 4, new[] { 2, 3, 5 } }, { 5, new[] { 4 } }
        };
        Console.WriteLine(ShortestDistance(graph, 1, 5));
    }
}

Verified output

3
Back to top ↑
#35Intermediatedynamic programmingarrays

Minimum coin change

The task

Problem

Given coin denominations and a target amount, find the minimum number of coins needed, or -1 if the amount cannot be formed.

How to think about it

Approach

Build answers from 0 upward. For every reachable amount, try adding each coin and keep the smallest count found for the new amount.

ComplexityTime O(amount × coins), space O(amount).

Complete C# solution

C#
using System;

class Program
{
    static int MinimumCoins(int[] coins, int amount)
    {
        int[] best = new int[amount + 1];
        for (int i = 0; i < best.Length; i++) best[i] = amount + 1;
        best[0] = 0;

        for (int value = 1; value <= amount; value++)
            foreach (int coin in coins)
                if (coin <= value) best[value] = Math.Min(best[value], best[value - coin] + 1);

        return best[amount] > amount ? -1 : best[amount];
    }

    static void Main()
    {
        Console.WriteLine(MinimumCoins(new[] { 1, 2, 5 }, 11));
    }
}

Verified output

3
Back to top ↑
#36Intermediatearraysreversal

Rotate an array to the right

The task

Problem

Rotate an integer array to the right by k positions in place. Values shifted past the end must wrap to the front.

How to think about it

Approach

Normalize k, reverse the whole array, then reverse the rotated prefix and remaining suffix. These three reversals place every value correctly without another array.

ComplexityTime O(n), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static void Reverse(int[] numbers, int left, int right)
    {
        while (left < right)
        {
            int temporary = numbers[left];
            numbers[left++] = numbers[right];
            numbers[right--] = temporary;
        }
    }

    static void RotateRight(int[] numbers, int positions)
    {
        if (numbers.Length == 0) return;
        positions = ((positions % numbers.Length) + numbers.Length) % numbers.Length;
        if (positions == 0) return;
        Reverse(numbers, 0, numbers.Length - 1);
        Reverse(numbers, 0, positions - 1);
        Reverse(numbers, positions, numbers.Length - 1);
    }

    static void Main()
    {
        int[] values = { 1, 2, 3, 4, 5 };
        RotateRight(values, 2);
        Console.WriteLine(string.Join(" ", values));
    }
}

Verified output

4 5 1 2 3
Back to top ↑
#37Intermediatematricesnested loops

Transpose a matrix

The task

Problem

Transpose a rectangular integer matrix so that each original row becomes a column.

How to think about it

Approach

Create a result whose row and column counts are swapped, then assign result[column, row] from input[row, column].

ComplexityTime O(rows x columns), space O(rows x columns).

Complete C# solution

C#
using System;

class Program
{
    static int[,] Transpose(int[,] matrix)
    {
        int rows = matrix.GetLength(0);
        int columns = matrix.GetLength(1);
        int[,] result = new int[columns, rows];

        for (int row = 0; row < rows; row++)
            for (int column = 0; column < columns; column++)
                result[column, row] = matrix[row, column];
        return result;
    }

    static void Main()
    {
        int[,] result = Transpose(new int[,] { { 1, 2, 3 }, { 4, 5, 6 } });
        for (int row = 0; row < result.GetLength(0); row++)
        {
            for (int column = 0; column < result.GetLength(1); column++)
                Console.Write((column == 0 ? "" : " ") + result[row, column]);
            Console.WriteLine();
        }
    }
}

Verified output

1 4
2 5
3 6
Back to top ↑
#38Intermediatestringscompression

Run-length encode a string

The task

Problem

Compress consecutive runs of the same character by writing the character followed by its run length.

How to think about it

Approach

Track the current run length while scanning. When the character changes, append the completed run and start counting the new one.

ComplexityTime O(n), space O(n) for the encoded result.

Complete C# solution

C#
using System;
using System.Text;

class Program
{
    static string Encode(string text)
    {
        if (text.Length == 0) return "";
        var encoded = new StringBuilder();
        int runLength = 1;

        for (int i = 1; i <= text.Length; i++)
        {
            if (i < text.Length && text[i] == text[i - 1])
            {
                runLength++;
                continue;
            }
            encoded.Append(text[i - 1]);
            encoded.Append(runLength);
            runLength = 1;
        }
        return encoded.ToString();
    }

    static void Main()
    {
        Console.WriteLine(Encode("aaabbccccdaa"));
    }
}

Verified output

a3b2c4d1a2
Back to top ↑
#39Intermediatedictionarystrings

First non-repeating character

The task

Problem

Return the first character that occurs exactly once in a string, or an empty string when every character repeats.

How to think about it

Approach

Count every character in one pass, then scan the original order again and return the first character whose count is one.

ComplexityTime O(n), space O(k), where k is the number of distinct characters.

Complete C# solution

C#
using System;
using System.Collections.Generic;

class Program
{
    static string FirstUnique(string text)
    {
        var counts = new Dictionary<char, int>();
        foreach (char symbol in text)
        {
            int count;
            counts.TryGetValue(symbol, out count);
            counts[symbol] = count + 1;
        }

        foreach (char symbol in text)
            if (counts[symbol] == 1) return symbol.ToString();
        return "";
    }

    static void Main()
    {
        Console.WriteLine(FirstUnique("swiss"));
    }
}

Verified output

w
Back to top ↑
#40Intermediatesliding windowdictionary

Longest substring without repeating characters

The task

Problem

Find the length of the longest contiguous substring whose characters are all distinct.

How to think about it

Approach

Maintain a sliding window start and each character's latest index. When a repeated character is inside the window, move the start just past its previous position.

ComplexityTime O(n), space O(k), where k is the character set size.

Complete C# solution

C#
using System;
using System.Collections.Generic;

class Program
{
    static int LongestDistinctSubstring(string text)
    {
        var lastSeen = new Dictionary<char, int>();
        int start = 0;
        int best = 0;

        for (int end = 0; end < text.Length; end++)
        {
            int previous;
            if (lastSeen.TryGetValue(text[end], out previous) && previous >= start)
                start = previous + 1;
            lastSeen[text[end]] = end;
            best = Math.Max(best, end - start + 1);
        }
        return best;
    }

    static void Main()
    {
        Console.WriteLine(LongestDistinctSubstring("abcabcbb"));
    }
}

Verified output

3
Back to top ↑
#41Intermediatedynamic programmingKadane's algorithm

Maximum subarray sum

The task

Problem

Find the largest possible sum of a non-empty contiguous subarray.

How to think about it

Approach

At each value, decide whether to extend the current subarray or start a new one. Track the best sum seen across all ending positions.

ComplexityTime O(n), space O(1).

Complete C# solution

C#
using System;

class Program
{
    static int MaximumSubarraySum(int[] numbers)
    {
        if (numbers.Length == 0) throw new ArgumentException("Array cannot be empty.");
        int endingHere = numbers[0];
        int best = numbers[0];

        for (int i = 1; i < numbers.Length; i++)
        {
            endingHere = Math.Max(numbers[i], endingHere + numbers[i]);
            best = Math.Max(best, endingHere);
        }
        return best;
    }

    static void Main()
    {
        Console.WriteLine(MaximumSubarraySum(new[] { -2, 1, -3, 4, -1, 2, 1, -5, 4 }));
    }
}

Verified output

6
Back to top ↑
#42Intermediatesortingintervals

Merge overlapping intervals

The task

Problem

Merge all overlapping closed intervals and return the smallest equivalent set of non-overlapping intervals.

How to think about it

Approach

Sort intervals by start value. Extend the last merged interval when the next one overlaps; otherwise append a new interval.

ComplexityTime O(n log n), space O(n) for the result.

Complete C# solution

C#
using System;
using System.Collections.Generic;

class Program
{
    class Interval
    {
        public int Start { get; set; }
        public int End { get; set; }
        public Interval(int start, int end) { Start = start; End = end; }
    }

    static List<Interval> MergeIntervals(List<Interval> intervals)
    {
        intervals.Sort((first, second) => first.Start.CompareTo(second.Start));
        var merged = new List<Interval>();

        foreach (Interval interval in intervals)
        {
            if (merged.Count == 0 || merged[merged.Count - 1].End < interval.Start)
                merged.Add(new Interval(interval.Start, interval.End));
            else
                merged[merged.Count - 1].End = Math.Max(merged[merged.Count - 1].End, interval.End);
        }
        return merged;
    }

    static void Main()
    {
        var intervals = new List<Interval>
        {
            new Interval(1, 3), new Interval(2, 6),
            new Interval(8, 10), new Interval(15, 18)
        };
        var labels = new List<string>();
        foreach (Interval interval in MergeIntervals(intervals))
            labels.Add(interval.Start + "-" + interval.End);
        Console.WriteLine(string.Join(", ", labels));
    }
}

Verified output

1-6, 8-10, 15-18
Back to top ↑
#43Intermediatedictionarysorting strings

Group anagrams

The task

Problem

Group words that are anagrams while preserving the order in which groups and words first appear.

How to think about it

Approach

Sort each word's characters to create a canonical signature. A dictionary finds the matching group, while a separate list preserves group insertion order.

ComplexityTime O(n x k log k), space O(n x k), where k is the maximum word length.

Complete C# solution

C#
using System;
using System.Collections.Generic;

class Program
{
    static List<List<string>> GroupAnagrams(string[] words)
    {
        var bySignature = new Dictionary<string, List<string>>();
        var groups = new List<List<string>>();

        foreach (string word in words)
        {
            char[] characters = word.ToCharArray();
            Array.Sort(characters);
            string signature = new string(characters);
            List<string> group;
            if (!bySignature.TryGetValue(signature, out group))
            {
                group = new List<string>();
                bySignature[signature] = group;
                groups.Add(group);
            }
            group.Add(word);
        }
        return groups;
    }

    static void Main()
    {
        foreach (var group in GroupAnagrams(new[] { "eat", "tea", "tan", "ate", "nat", "bat" }))
            Console.WriteLine(string.Join(",", group));
    }
}

Verified output

eat,tea,ate
tan,nat
bat
Back to top ↑
#44Intermediatelinked listfast and slow pointers

Detect a linked-list cycle

The task

Problem

Determine whether a singly linked list contains a cycle without storing every visited node.

How to think about it

Approach

Move one pointer by one node and another by two. They must eventually meet inside a cycle; otherwise the faster pointer reaches the end.

ComplexityTime O(n), space O(1).

Complete C# solution

C#
using System;

class Program
{
    class Node
    {
        public int Value { get; private set; }
        public Node Next { get; set; }
        public Node(int value) { Value = value; }
    }

    static bool HasCycle(Node head)
    {
        Node slow = head;
        Node fast = head;
        while (fast != null && fast.Next != null)
        {
            slow = slow.Next;
            fast = fast.Next.Next;
            if (slow == fast) return true;
        }
        return false;
    }

    static void Main()
    {
        Node first = new Node(1);
        Node second = new Node(2);
        Node third = new Node(3);
        first.Next = second;
        second.Next = third;
        third.Next = second;
        Console.WriteLine(HasCycle(first));
    }
}

Verified output

True
Back to top ↑
#45Intermediatebinary treerecursion

Calculate binary-tree height

The task

Problem

Calculate the height of a binary tree as the number of nodes on its longest root-to-leaf path. An empty tree has height zero.

How to think about it

Approach

Recursively calculate the left and right subtree heights, choose the larger one, and add one for the current node.

ComplexityTime O(n), call-stack space O(h), where h is the tree height.

Complete C# solution

C#
using System;

class Program
{
    class Node
    {
        public int Value { get; private set; }
        public Node Left { get; set; }
        public Node Right { get; set; }
        public Node(int value) { Value = value; }
    }

    static int Height(Node node)
    {
        if (node == null) return 0;
        return 1 + Math.Max(Height(node.Left), Height(node.Right));
    }

    static void Main()
    {
        Node root = new Node(8);
        root.Left = new Node(4);
        root.Right = new Node(12);
        root.Left.Left = new Node(2);
        Console.WriteLine(Height(root));
    }
}

Verified output

3
Back to top ↑
#46Intermediatebinary treedepth-first search

Inorder binary-tree traversal

The task

Problem

Return the values of a binary tree in left-subtree, root, right-subtree order.

How to think about it

Approach

Recursively visit the left child, record the current node, then visit the right child. A binary search tree is produced in sorted order.

ComplexityTime O(n), space O(n) for the result plus O(h) call-stack space.

Complete C# solution

C#
using System;
using System.Collections.Generic;

class Program
{
    class Node
    {
        public int Value { get; private set; }
        public Node Left { get; set; }
        public Node Right { get; set; }
        public Node(int value) { Value = value; }
    }

    static void Traverse(Node node, List<int> values)
    {
        if (node == null) return;
        Traverse(node.Left, values);
        values.Add(node.Value);
        Traverse(node.Right, values);
    }

    static void Main()
    {
        Node root = new Node(4);
        root.Left = new Node(2);
        root.Right = new Node(5);
        root.Left.Left = new Node(1);
        root.Left.Right = new Node(3);
        var values = new List<int>();
        Traverse(root, values);
        Console.WriteLine(string.Join(" ", values));
    }
}

Verified output

1 2 3 4 5
Back to top ↑
#47Intermediategriddepth-first search

Flood fill a grid

The task

Problem

Recolor the connected region containing a starting cell. Cells connect vertically and horizontally when they have the same original color.

How to think about it

Approach

Remember the original color, recolor the current cell, and recursively visit valid neighbors that still have the original color.

ComplexityTime O(rows x columns), call-stack space O(rows x columns) in the worst case.

Complete C# solution

C#
using System;

class Program
{
    static void Fill(int[,] image, int row, int column, int original, int replacement)
    {
        if (row < 0 || row >= image.GetLength(0) ||
            column < 0 || column >= image.GetLength(1) ||
            image[row, column] != original) return;

        image[row, column] = replacement;
        Fill(image, row - 1, column, original, replacement);
        Fill(image, row + 1, column, original, replacement);
        Fill(image, row, column - 1, original, replacement);
        Fill(image, row, column + 1, original, replacement);
    }

    static void FloodFill(int[,] image, int row, int column, int replacement)
    {
        int original = image[row, column];
        if (original != replacement) Fill(image, row, column, original, replacement);
    }

    static void Main()
    {
        int[,] image = { { 1, 1, 1 }, { 1, 1, 0 }, { 1, 0, 1 } };
        FloodFill(image, 1, 1, 2);
        for (int row = 0; row < image.GetLength(0); row++)
        {
            for (int column = 0; column < image.GetLength(1); column++)
                Console.Write((column == 0 ? "" : " ") + image[row, column]);
            Console.WriteLine();
        }
    }
}

Verified output

2 2 2
2 2 0
2 0 1
Back to top ↑
#48Intermediatebacktrackingrecursion

Generate all string permutations

The task

Problem

Generate every permutation of a string whose characters are distinct.

How to think about it

Approach

Fix one position at a time by swapping each available character into it, recurse for the remaining positions, then undo the swap.

ComplexityTime O(n x n!), call-stack space O(n), excluding the output.

Complete C# solution

C#
using System;
using System.Collections.Generic;

class Program
{
    static void Generate(char[] characters, int position, List<string> results)
    {
        if (position == characters.Length)
        {
            results.Add(new string(characters));
            return;
        }

        for (int i = position; i < characters.Length; i++)
        {
            char temporary = characters[position];
            characters[position] = characters[i];
            characters[i] = temporary;
            Generate(characters, position + 1, results);
            temporary = characters[position];
            characters[position] = characters[i];
            characters[i] = temporary;
        }
    }

    static void Main()
    {
        var results = new List<string>();
        Generate("ABC".ToCharArray(), 0, results);
        Console.WriteLine(string.Join(" ", results));
    }
}

Verified output

ABC ACB BAC BCA CBA CAB
Back to top ↑
#49Intermediatedynamic programmingstrings

Calculate edit distance

The task

Problem

Find the minimum number of single-character insertions, deletions, and replacements needed to transform one string into another.

How to think about it

Approach

Build a table for all prefix pairs. Matching final characters reuse the diagonal value; otherwise add one to the best insertion, deletion, or replacement state.

ComplexityTime O(n x m), space O(n x m).

Complete C# solution

C#
using System;

class Program
{
    static int EditDistance(string first, string second)
    {
        int[,] edits = new int[first.Length + 1, second.Length + 1];
        for (int i = 0; i <= first.Length; i++) edits[i, 0] = i;
        for (int j = 0; j <= second.Length; j++) edits[0, j] = j;

        for (int i = 1; i <= first.Length; i++)
        {
            for (int j = 1; j <= second.Length; j++)
            {
                if (first[i - 1] == second[j - 1])
                    edits[i, j] = edits[i - 1, j - 1];
                else
                    edits[i, j] = 1 + Math.Min(edits[i - 1, j - 1],
                        Math.Min(edits[i - 1, j], edits[i, j - 1]));
            }
        }
        return edits[first.Length, second.Length];
    }

    static void Main()
    {
        Console.WriteLine(EditDistance("kitten", "sitting"));
    }
}

Verified output

3
Back to top ↑
#50Intermediatedynamic programmingoptimization

0/1 knapsack

The task

Problem

Choose items with given weights and values to maximize total value without exceeding a capacity. Each item may be used at most once.

How to think about it

Approach

Store the best value for every capacity. Process capacities downward for each item so that an item cannot contribute more than once in the same iteration.

ComplexityTime O(items x capacity), space O(capacity).

Complete C# solution

C#
using System;

class Program
{
    static int MaximumValue(int[] weights, int[] values, int capacity)
    {
        if (weights.Length != values.Length)
            throw new ArgumentException("Weights and values must have equal lengths.");

        int[] best = new int[capacity + 1];
        for (int item = 0; item < weights.Length; item++)
            for (int limit = capacity; limit >= weights[item]; limit--)
                best[limit] = Math.Max(best[limit], best[limit - weights[item]] + values[item]);
        return best[capacity];
    }

    static void Main()
    {
        Console.WriteLine(MaximumValue(
            new[] { 2, 3, 4, 5 },
            new[] { 3, 4, 5, 8 },
            5));
    }
}

Verified output

8
Back to top ↑

Common questions

C# problem-solving FAQ

How should I use these C# problems?+

Attempt each problem before reading its solution. Test normal, boundary, and invalid inputs, then compare your algorithm and complexity with the worked answer.

Can I run every solution online?+

Yes. Use the Run in compiler button above any solution. It transfers the complete program to BuildQuill's C# compiler and runs it immediately.

Are the displayed outputs verified?+

Yes. All 50 programs were executed with the same Mono runtime used by BuildQuill's compiler, and every displayed output matches the program result.

Do I need to memorize every algorithm?+

No. Learn to recognize patterns such as two pointers, hash-based lookup, stacks, breadth-first search, recursion, and dynamic programming. Reconstructing an approach matters more than memorizing code.

Keep practicing

Change the inputs. Break an assumption.

The fastest way to understand a solution is to edit it, predict what changes, and run it again.

Open the compiler