Modular Arithmetic Basics in DSA Go - Time & Space Complexity
We want to understand how the time needed to do modular arithmetic operations changes as numbers get bigger.
Specifically, how does the cost grow when we do repeated modular calculations?
Analyze the time complexity of the following code snippet.
package main
func modAdd(a, b, m int) int {
return (a + b) % m
}
func modMul(a, b, m int) int {
return (a * b) % m
}
func modExp(base, exp, m int) int {
result := 1
for exp > 0 {
if exp%2 == 1 {
result = (result * base) % m
}
base = (base * base) % m
exp = exp / 2
}
return result
}
This code shows modular addition, multiplication, and fast modular exponentiation using repeated squaring.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The loop inside
modExprepeats while halving the exponent. - How many times: The loop runs about
log_2(exp)times because the exponent is divided by 2 each step.
As the exponent grows, the number of loop steps grows slowly because we halve the exponent each time.
| Input Size (exp) | Approx. Operations |
|---|---|
| 10 | About 4 steps |
| 100 | About 7 steps |
| 1000 | About 10 steps |
Pattern observation: Doubling the exponent adds only one more step, so growth is very slow.
Time Complexity: O(log n)
This means the time to compute modular exponentiation grows slowly as the exponent gets bigger, making it efficient for large numbers.
[X] Wrong: "Modular exponentiation takes as long as the exponent value because it loops that many times."
[OK] Correct: The loop actually halves the exponent each time, so it runs much fewer times than the exponent's value.
Understanding modular arithmetic time complexity helps you solve problems with large numbers efficiently, a common skill interviewers look for.
"What if we changed the modular exponentiation to use simple repeated multiplication without halving the exponent? How would the time complexity change?"
Practice
7 % 3 in modular arithmetic?Solution
Step 1: Understand the modulus operation
The modulus operator (%) gives the remainder when the first number is divided by the second.Step 2: Calculate 7 % 3
7 divided by 3 is 2 with a remainder of 1, so 7 % 3 = 1.Final Answer:
1 -> Option CQuick Check:
7 % 3 = 1 [OK]
- Confusing modulus with division
- Using quotient instead of remainder
- Mixing up operands order
a and b in Go?Solution
Step 1: Recall Go syntax for modulus
In Go, the modulus operator is the percent sign (%) used between two integers.Step 2: Identify correct syntax
mod := a % b usesa % b, which is the correct way to compute modulus in Go.Final Answer:
mod := a % b -> Option AQuick Check:
Go uses % for modulus [OK]
- Using 'mod' keyword instead of %
- Double percent signs %%
- Using function call syntax for modulus
package main
import "fmt"
func main() {
a := 14
b := 5
fmt.Println(a % b)
}Solution
Step 1: Understand the code variables
Variableais 14 andbis 5.Step 2: Calculate 14 % 5
14 divided by 5 is 2 with remainder 4, so output is 4.Final Answer:
4 -> Option BQuick Check:
14 % 5 = 4 [OK]
- Using division result instead of remainder
- Confusing operands order
- Misreading variable values
package main
import "fmt"
func main() {
var a, b int = 10, 3
result := a mod b
fmt.Println(result)
}Solution
Step 1: Check modulus operator usage
The code usesa mod b, but Go does not have a 'mod' keyword.Step 2: Correct operator in Go
Go uses the percent sign (%) for modulus, so it should bea % b.Final Answer:
Using 'mod' instead of '%' operator -> Option DQuick Check:
Modulus in Go uses % [OK]
- Using 'mod' keyword
- Assuming modulus needs import
- Incorrect variable declaration assumptions
a = 123456789 and b = 987654321 is divided by 1000. Which expression correctly uses modular arithmetic to compute this efficiently in Go?Solution
Step 1: Understand modular addition property
Modular arithmetic allows (a + b) % m = ((a % m) + (b % m)) % m to avoid large sums.Step 2: Apply property to given numbers
Compute (a % 1000 + b % 1000) % 1000 to get remainder without overflow.Final Answer:
(a % 1000 + b % 1000) % 1000 -> Option AQuick Check:
(a + b) % 1000 = ((a % 1000) + (b % 1000)) % 1000 [OK]
- Adding remainders without final modulus
- Not applying modulus before addition
- Misplacing parentheses
Ready to prove it?
Pass the test and this pattern moves unknown
