Problem
The softmax function turns a list of scores (logits) into probabilities. Language models use it to choose the next word:
softmax(x)_i = e^(x_i) / (e^(x_1) + e^(x_2) + … + e^(x_n))
Large scores make e^x overflow, so first subtract the largest score from every score. The result is mathematically the same.
Implement softmax(logits).
Input
logits: A list of scores.
Output
Return the list of probabilities, in the same order. They are all between 0 and 1 and add up to 1.
Constraints
1 ≤ length ≤ 1,000
-1,000 ≤ each score ≤ 1,000
Examples
Input:
logits = [1.0, 2.0, 3.0]
Expected output:
expected = [0.090031, 0.244728, 0.665241]
Input:
std::vector<double> logits = {1.0, 2.0, 3.0};
Expected output:
std::vector<double> expected = {0.090031, 0.244728, 0.665241};
Input:
double[] logits = new double[] {1.0, 2.0, 3.0};
Expected output:
double[] expected = new double[] {0.090031, 0.244728, 0.665241};
Explanation
e¹ ≈ 2.718, e² ≈ 7.389 and e³ ≈ 20.086 add up to 30.193, so the probabilities are about [0.090031, 0.244728, 0.665241].
Input:
logits = [1000.0, 1000.0]
Expected output:
expected = [0.5, 0.5]
Input:
std::vector<double> logits = {1000.0, 1000.0};
Expected output:
std::vector<double> expected = {0.5, 0.5};
Input:
double[] logits = new double[] {1000.0, 1000.0};
Expected output:
double[] expected = new double[] {0.5, 0.5};
Explanation
Computing e^1000 directly overflows. Subtracting the maximum gives [0, 0], and e⁰ / (e⁰ + e⁰) = 0.5 for both.
How to approach it
Try on your own first, then open one hint at a time.
Hint 1
Subtract the largest logit before exponentiating so the largest transformed score becomes zero and overflow is avoided.
Hint 2
Compute each exponent, sum them once, then divide every exponent by that total to get probabilities.
Hint 3
Make sure the returned values stay in the same order as the input and still sum to one after normalization.
Expected complexity
O(n) time, O(n) extra space
References
This challenge is adapted for CodeUtility. Follow the statement and constraints above.