Radix Sort Algorithm in DSA Go - Time & Space Complexity
We want to understand how the time taken by Radix Sort changes as the input size grows.
Specifically, how the number of digits and elements affect the work done.
Analyze the time complexity of the following Radix Sort code snippet.
func radixSort(arr []int) []int {
max := arr[0]
for _, v := range arr {
if v > max {
max = v
}
}
exp := 1
n := len(arr)
output := make([]int, n)
for max/exp > 0 {
count := make([]int, 10)
for i := 0; i < n; i++ {
count[(arr[i]/exp)%10]++
}
for i := 1; i < 10; i++ {
count[i] += count[i-1]
}
for i := n - 1; i >= 0; i-- {
output[count[(arr[i]/exp)%10]-1] = arr[i]
count[(arr[i]/exp)%10]--
}
copy(arr, output)
exp *= 10
}
return arr
}
This code sorts integers by processing digits from least to most significant.
Look for loops and repeated steps:
- Primary operation: Counting sort on each digit place.
- How many times: Once for each digit of the largest number.
- Inside each digit pass, loops run over all elements multiple times.
The work depends on two things: number of elements (n) and number of digits (d).
| Input Size (n) | Digits (d) | Approx. Operations |
|---|---|---|
| 10 | 2 | About 20 loops over elements |
| 100 | 3 | About 300 loops over elements |
| 1000 | 4 | About 4000 loops over elements |
Pattern observation: Operations grow roughly by n times d, so doubling n or d roughly doubles work.
Time Complexity: O(d * n)
This means the time grows linearly with the number of elements and the number of digits in the largest number.
[X] Wrong: "Radix Sort always runs in linear time O(n)."
[OK] Correct: The number of digits (d) matters; if numbers are very large, d grows and so does time.
Understanding Radix Sort's time complexity helps you explain when it is efficient and when it might not be.
This skill shows you can analyze algorithms beyond simple loops, a key part of problem solving.
"What if we changed the base from 10 to 2 (binary digits)? How would the time complexity change?"
Practice
Radix Sort Algorithm?Solution
Step 1: Understand Radix Sort approach
Radix Sort sorts numbers by grouping digits and sorting them digit by digit, starting from the least significant digit.Step 2: Compare with other sorting methods
Unlike comparison-based sorts (like bubble or merge sort), Radix Sort processes digits individually without direct element comparisons.Final Answer:
Sort numbers by processing individual digits from least to most significant -> Option BQuick Check:
Radix Sort = Digit-wise sorting [OK]
- Thinking Radix Sort compares elements directly
- Confusing Radix Sort with divide and conquer methods
- Assuming it swaps adjacent elements like bubble sort
Solution
Step 1: Identify bucket type needed
Radix Sort uses buckets to hold multiple integers per digit, so each bucket must be a slice of ints.Step 2: Choose correct slice initialization
Usingmake([][]int, 10)creates a slice of 10 slices, perfect for buckets 0-9.Final Answer:
buckets := make([][]int, 10) -> Option CQuick Check:
Slice of slices for buckets = buckets := make([][]int, 10) [OK]
- Using single int slice instead of slice of slices
- Using array instead of slice for dynamic buckets
- Initializing empty slice without length
[170, 45, 75, 90, 802, 24, 2, 66]?
package main
import "fmt"
func main() {
arr := []int{170, 45, 75, 90, 802, 24, 2, 66}
radixSort(arr)
fmt.Println(arr)
}
func radixSort(arr []int) {
max := getMax(arr)
exp := 1
for max/exp > 0 {
countSort(arr, exp)
exp *= 10
}
}
func getMax(arr []int) int {
max := arr[0]
for _, v := range arr {
if v > max {
max = v
}
}
return max
}
func countSort(arr []int, exp int) {
n := len(arr)
output := make([]int, n)
count := make([]int, 10)
for i := 0; i < n; i++ {
index := (arr[i] / exp) % 10
count[index]++
}
for i := 1; i < 10; i++ {
count[i] += count[i-1]
}
for i := n - 1; i >= 0; i-- {
index := (arr[i] / exp) % 10
output[count[index]-1] = arr[i]
count[index]--
}
for i := 0; i < n; i++ {
arr[i] = output[i]
}
}Solution
Step 1: Understand Radix Sort process on given array
Radix Sort sorts by digits from least significant to most significant. After sorting by units, tens, and hundreds place, the array becomes sorted.Step 2: Trace final sorted array
The final sorted array is ascending: [2, 24, 45, 66, 75, 90, 170, 802].Final Answer:
[2 24 45 66 75 90 170 802] -> Option DQuick Check:
Radix Sort output = Sorted ascending array [OK]
- Confusing order of digits processed
- Misreading output as original array
- Mixing up output with descending order
func countSort(arr []int, exp int) {
n := len(arr)
output := make([]int, n)
count := make([]int, 10)
for i := 0; i < n; i++ {
index := (arr[i] / exp) % 10
count[index]++
}
for i := 1; i < 10; i++ {
count[i] += count[i-1]
}
for i := 0; i < n; i++ {
index := (arr[i] / exp) % 10
output[count[index]-1] = arr[i]
count[index]--
}
for i := 0; i < n; i++ {
arr[i] = output[i]
}
}Solution
Step 1: Check order of placing elements in output
To maintain stable sorting, elements must be placed from right to left (backwards) in output.Step 2: Identify incorrect loop direction
The code uses a forward loop (0 to n-1) which breaks stability; it should loop from n-1 down to 0.Final Answer:
The last for loop should iterate backwards from n-1 to 0 -> Option AQuick Check:
Stable sort needs backward loop [OK]
- Looping forward breaks stability
- Changing count array size unnecessarily
- Misunderstanding index calculation
Solution
Step 1: Handle varying string lengths
Pad strings with leading zeros so all have equal length, ensuring digit positions align.Step 2: Apply Radix Sort digit by digit from right to left
After padding, sort from least significant digit (rightmost) to most significant (leftmost) to maintain correct order.Final Answer:
Pad all strings with leading zeros to equal length, then sort digit by digit from right to left -> Option AQuick Check:
Padding equalizes length for Radix Sort [OK]
- Sorting by length first breaks digit alignment
- Converting strings to int may overflow or lose leading zeros
- Sorting only first character ignores full number
Ready to prove it?
Pass the test and this pattern moves unknown
