C# Priority Queue
Tags: csharp, algorithms
Published: 2024-04-29 14:50:09

Imagine a heap as a special kind of tree where each parent node has a value that's less than or equal to the values of its children. In simpler terms, you can think of it as a tree where the parent node is always smaller (or larger) than its children. This property makes heaps perfect for priority queues, where the topmost element (root) always has the highest (or lowest) priority.

By default, the .NET class [PriorityQueue](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.priorityqueue-2?view=net-8.0) provide us with a Min Heap. This means that the smallest element is always at the root (every parent node has a value less than or equal to the values of its children), however, we are allowed to pass a "Comparer" function to modify this behavior.

This is what I want to show you in this article. We are going to implement a Max Heap using the Priority Queue class, introduced in .NET 6

We will resolve this [leetcode exercise](https://leetcode.com/problems/largest-number-after-digit-swaps-by-parity/):

> You are given a positive integer num. You may swap any two digits of num that have the same parity (i.e. both odd digits or both even digits).

> 
Return the largest possible value of num after any number of swaps.

Solution:  This method initializes two priority queues, pqOdd and pqEven, to store odd and even digits respectively in descending order. It then iterates through each digit of the input number, enqueuing them into the appropriate priority queue based on their parity (odd or even) and marking their position in the result list accordingly. After all digits are processed, it dequeues the digits from the priority queues in the order specified by the result list, effectively rearranging them to form the largest integer possible. Finally, it converts the rearranged digits back into an integer and returns it.

Note that we pass a Comparer function and therefore achieve the behavior of the priority queue as a max heap

```
public class Solution
{
    // Method to find the largest possible integer by rearranging the digits of the input number
    public int LargestInteger(int num)
    {
        // Initialize two priority queues to store digits: pqOdd for odd digits and pqEven for even digits
        // Priority queues are initialized with custom comparers to ensure descending order
        PriorityQueue<int, int> pqOdd = new PriorityQueue<int, int>(Comparer<int>.Create((a, b) => b - a));
        PriorityQueue<int, int> pqEven = new PriorityQueue<int, int>(Comparer<int>.Create((a, b) => b - a));

        // List to store the result digits
        List<int> result = new List<int>();

        // Iterate through each digit of the input number
        foreach (char digit in num.ToString())
        {
            // Convert the character digit to an integer
            int digitInt = int.Parse(digit.ToString());

            // Check if the digit is even or odd
            if (digitInt % 2 == 0) {
                // If even, enqueue the digit into pqOdd with the digit itself as priority
                pqOdd.Enqueue(digitInt, digitInt);
                // Add 0 to the result list to mark the position of the even digit
                result.Add(0);
            }
            else {
                // If odd, enqueue the digit into pqEven with the digit itself as priority
                pqEven.Enqueue(digitInt, digitInt);
                // Add 1 to the result list to mark the position of the odd digit
                result.Add(1);
            };
        }

        // Iterate through the result list to rearrange the digits
        for (int i = 0; i < result.Count(); i++)
        {
            // If the result at index i is 0, dequeue the top element from pqOdd and update the result list
            if (result[i] == 0)
            {
                result[i] = pqOdd.Dequeue();
            }
            // If the result at index i is 1, dequeue the top element from pqEven and update the result list
            else
            {
                result[i] = pqEven.Dequeue();
            }
        }

        // Convert the result list to a string and then to an integer, and return it
        return int.Parse(string.Join("", result));
    }
}

```