Bird
Raised Fist0
DSA Goprogramming~5 mins

Quick Sort Partition Lomuto and Hoare in DSA Go - Time & Space Complexity

Choose your learning style10 modes available
Time Complexity: Quick Sort Partition Lomuto and Hoare
O(n)
Understanding Time Complexity

We want to understand how the time taken by Quick Sort's partition steps grows as the input size increases.

Specifically, we compare Lomuto and Hoare partition methods to see how their operations scale.

Scenario Under Consideration

Analyze the time complexity of these two partition functions used in Quick Sort.


// Lomuto partition
func lomutoPartition(arr []int, low, high int) int {
    pivot := arr[high]
    i := low - 1
    for j := low; j < high; j++ {
        if arr[j] <= pivot {
            i++
            arr[i], arr[j] = arr[j], arr[i]
        }
    }
    arr[i+1], arr[high] = arr[high], arr[i+1]
    return i + 1
}

// Hoare partition
func hoarePartition(arr []int, low, high int) int {
    pivot := arr[low]
    i := low - 1
    j := high + 1
    for {
        for {
            i++
            if arr[i] >= pivot {
                break
            }
        }
        for {
            j--
            if arr[j] <= pivot {
                break
            }
        }
        if i >= j {
            return j
        }
        arr[i], arr[j] = arr[j], arr[i]
    }
}
    

These functions rearrange elements around a pivot to help Quick Sort divide the array.

Identify Repeating Operations

Both partitions use loops to compare and swap elements.

  • Primary operation: Comparing elements to the pivot and swapping if needed.
  • How many times: Each element between low and high is checked once in Lomuto; in Hoare, pointers move inward checking elements until they cross.
How Execution Grows With Input

As the number of elements (n) increases, the number of comparisons and swaps grows roughly in proportion to n.

Input Size (n)Approx. Operations
10About 10 comparisons and some swaps
100About 100 comparisons and swaps
1000About 1000 comparisons and swaps

Pattern observation: The operations increase linearly as input size grows.

Final Time Complexity

Time Complexity: O(n)

This means the partition step takes time proportional to the number of elements it processes.

Common Mistake

[X] Wrong: "Partitioning takes constant time because it just picks a pivot."

[OK] Correct: Partitioning compares and swaps many elements, so its time grows with input size, not constant.

Interview Connect

Understanding partition time helps you explain Quick Sort's efficiency and why pivot choice matters.

Self-Check

"What if we used a random pivot instead of fixed ends? How would the partition time complexity change?"

Practice

(1/5)
1. What is the main difference between Lomuto and Hoare partition schemes in Quick Sort?
easy
A. Lomuto uses a single pointer to partition, Hoare uses two pointers moving inward
B. Lomuto sorts the array in descending order, Hoare sorts in ascending order
C. Lomuto requires extra memory, Hoare works in-place
D. Lomuto always picks the last element as pivot, Hoare always picks the first

Solution

  1. Step 1: Understand Lomuto partition

    Lomuto partition uses one pointer to track the boundary of smaller elements and swaps elements accordingly.
  2. Step 2: Understand Hoare partition

    Hoare partition uses two pointers starting from both ends moving inward to swap elements around the pivot.
  3. Final Answer:

    Lomuto uses a single pointer to partition, Hoare uses two pointers moving inward -> Option A
  4. Quick Check:

    Partition pointers = single vs two [OK]
Hint: Remember: Lomuto single pointer, Hoare two pointers inward [OK]
Common Mistakes:
  • Confusing pivot selection with partition method
  • Thinking Lomuto uses two pointers
  • Assuming Hoare needs extra memory
2. Which of the following is the correct Lomuto partition function header in Go?
easy
A. func lomutoPartition(arr []int, low int, high int) int
B. func lomutoPartition(arr []int) int
C. func lomutoPartition(arr []int, pivot int) int
D. func lomutoPartition(arr []int, start int, end int) bool

Solution

  1. Step 1: Check parameters needed for Lomuto

    Lomuto partition requires the array and indices low and high to define the subarray.
  2. Step 2: Check return type

    It returns an integer index of the pivot after partitioning.
  3. Final Answer:

    func lomutoPartition(arr []int, low int, high int) int -> Option A
  4. Quick Check:

    Function signature = arr, low, high, returns int [OK]
Hint: Lomuto needs array and low, high indices, returns pivot index [OK]
Common Mistakes:
  • Omitting low and high parameters
  • Returning bool instead of int
  • Passing pivot as parameter explicitly
3. What is the output array after applying Lomuto partition on [8, 3, 7, 6, 2] with pivot as last element?
medium
A. [8, 3, 7, 6, 2]
B. [3, 2, 7, 6, 8]
C. [2, 3, 7, 6, 8]
D. [2, 3, 6, 7, 8]

Solution

  1. Step 1: Identify pivot and initialize pointers

    Pivot is last element 2. Initialize i = low - 1 = -1.
  2. Step 2: Iterate and swap elements smaller than pivot

    Check elements: 8 > 2 no swap, 3 > 2 no swap, 7 > 2 no swap, 6 > 2 no swap. i stays -1. Finally swap pivot with arr[i+1] = arr[0].
  3. Final Answer:

    [2, 3, 6, 7, 8] -> Option D
  4. Quick Check:

    Pivot 2 placed at start, smaller elements left [OK]
Hint: Pivot last element, swap smaller left, pivot next [OK]
Common Mistakes:
  • Swapping elements incorrectly
  • Not updating i pointer properly
  • Confusing pivot position after partition
4. Given this Hoare partition code snippet in Go, what is the bug?
func hoarePartition(arr []int, low, high int) int {
    pivot := arr[low]
    i := low - 1
    j := high + 1
    for {
        for arr[i] < pivot {
            i++
        }
        for arr[j] > pivot {
            j--
        }
        if i >= j {
            return j
        }
        arr[i], arr[j] = arr[j], arr[i]
    }
}
medium
A. The inner loops should use <= and >= instead of < and >
B. Pivot should be arr[high] instead of arr[low]
C. i and j initialization should be i = low, j = high
D. The swap should happen after checking i > j

Solution

  1. Step 1: Check pointer initialization

    In Hoare partition, i starts at low and j at high, not outside the array bounds.
  2. Step 2: Understand loop conditions

    Starting i at low - 1 and j at high + 1 causes index out of range errors during arr[i] and arr[j] access.
  3. Final Answer:

    i and j initialization should be i = low, j = high -> Option C
  4. Quick Check:

    Pointer start = low, high [OK]
Hint: Hoare pointers start at low and high, not outside [OK]
Common Mistakes:
  • Initializing pointers outside array bounds
  • Using wrong pivot element
  • Swapping before pointer check
5. You want to sort an array with many duplicate elements efficiently. Which partition scheme is better and why?
hard
A. Lomuto, because it handles duplicates by placing them all on one side
B. Hoare, because it partitions elements more evenly and reduces swaps with duplicates
C. Lomuto, because it uses two pointers to handle duplicates quickly
D. Hoare, because it always picks the last element as pivot

Solution

  1. Step 1: Consider duplicate handling in Lomuto

    Lomuto tends to put duplicates on one side, causing unbalanced partitions and more recursive calls.
  2. Step 2: Consider duplicate handling in Hoare

    Hoare's two-pointer approach partitions more evenly, reducing swaps and improving performance with duplicates.
  3. Final Answer:

    Hoare, because it partitions elements more evenly and reduces swaps with duplicates -> Option B
  4. Quick Check:

    Duplicates handled better by Hoare [OK]
Hint: Hoare partitions evenly, better for duplicates [OK]
Common Mistakes:
  • Assuming Lomuto is better for duplicates
  • Confusing pivot choice with partition efficiency
  • Ignoring swap count impact
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard