Problem
You are given a string of digits representing a non-negative integer. Find the largest odd number that can be formed by taking a non-empty prefix of that string, and return it as a string. If no odd prefix exists, return an empty string.
- Input:
num = "35427" - Output:
"35427" - Explanation: The full number ends in 7, which is odd, so the entire string is the largest valid prefix.
Counter-example: "4206" โ "" because every prefix ends in an even digit (6, 0, 2, or 4).
Intuition
An integer is odd if and only if its last digit is odd. Since a longer prefix always represents a larger number (more digits), the optimal strategy is to find the rightmost odd digit โ that gives us the longest prefix that is still an odd number. We scan from the right and return the prefix ending at the first odd digit we find.
Solution โ Right-to-Left Scan
Walk the string backwards until you hit an odd digit. Return the prefix up to and including that position.
- Start at the last character and move left.
- For each character, check whether its digit value is odd (digit % 2 == 1).
- On the first odd digit found, return the prefix from index 0 through that index (inclusive).
- If the entire string was scanned without finding an odd digit, return
"".
1def largestOddNumber(num: str) -> str:
2 for i in range(len(num) - 1, -1, -1):
3 if int(num[i]) % 2 == 1: # odd digit found โ this is the cut point
4 return num[:i + 1]
5 return ""Time: O(n) โ single pass through at most n characters.
Space: O(1) extra โ the returned substring is the output, not auxiliary storage.
Complexity Summary
| Approach | Time | Space | When to use |
|---|---|---|---|
| Right-to-Left Scan | O(n) | O(1) | Always โ this is the only approach needed |
Common Mistakes
- Off-by-one on the substring bound: returning
num[:i]instead ofnum[:i+1]โ the odd digit at indeximust be included in the result, otherwise you return a prefix that ends one position too early. - Converting the whole string to an integer: numbers up to 10โต digits long overflow any primitive type; the digit parity check only needs the last character, never the full numeric value.
- Scanning left to right and returning the first odd prefix: this gives the shortest odd prefix (e.g.
"5"from"52"), not the largest. Scanning right to left gives the longest prefix with an odd final digit, which is always the numerically largest. - Forgetting the all-even case: if no odd digit exists anywhere, the loop exits without returning โ make sure to explicitly return
""after the loop. - Using
num[i] % 2instead of(num[i] - '0') % 2in Java/C++:num[i]in those languages is a char, not an int; its ASCII value is not the same as its digit value, so the modulo check would be wrong.
Related Problems
reverse-integerโ digit-by-digit number manipulation using modulo and divisionpalindrome-numberโ determining a numeric property by inspecting individual digitslargest-numberโ arranging digits/numbers in a string to maximize a numeric valueplus-oneโ right-to-left digit traversal with carry propagationfind-numbers-with-even-number-of-digitsโ digit counting and property checking on numeric values