Ambiguous Coordinates
MedPrompt
We had some 2-dimensional coordinates, like "(1, 3)" or "(2, 0.5)". Then, we removed all commas, decimal points, and spaces and ended up with the string s.
- For example,
"(1, 3)"becomess = "(13)"and"(2, 0.5)"becomess = "(205)".
Return a list of strings representing all possibilities for what our original coordinates could have been.
Our original representation never had extraneous zeroes, so we never started with numbers like "00", "0.0", "0.00", "1.0", "001", "00.01", or any other number that can be represented with fewer digits. Also, a decimal point within a number never occurs without at least one digit occurring before it, so we never started with numbers like ".1".
The final answer list can be returned in any order. All coordinates in the final answer have exactly one space between them (occurring after the comma.)
Example 1:
Input: s = "(123)"
Output: ["(1, 2.3)","(1, 23)","(1.2, 3)","(12, 3)"]Example 2:
Input: s = "(0123)"
Output: ["(0, 1.23)","(0, 12.3)","(0, 123)","(0.1, 2.3)","(0.1, 23)","(0.12, 3)"]
Explanation: 0.0, 00, 0001 or 00.01 are not allowed.Example 3:
Input: s = "(00011)"
Output: ["(0, 0.011)","(0.001, 1)"]
Constraints:
4 <= s.length <= 12s[0] == '('ands[s.length - 1] == ')'.- The rest of
sare digits.
Approaches
2 approaches with complexity analysis and trade-offs.
This approach systematically explores all possibilities. The core idea is to split the input digit string into two parts, x_str and y_str, which will form the x and y coordinates. For each split, we generate all valid numerical interpretations for x_str and y_str. A number can be an integer or a decimal, subject to certain rules about leading and trailing zeros. Finally, we combine every valid x-interpretation with every valid y-interpretation to form the final coordinate pairs.
Algorithm
- Extract the digit string
digitsfrom the inputsby removing the parentheses. Let its length ben. - Create a list
resultto store the final coordinate strings. - Loop with an index
ifrom 1 ton-1. Thisirepresents the split point. - In each iteration, split
digitsinto two substrings:s1 = digits.substring(0, i)ands2 = digits.substring(i). - Call a helper function
generateValidNumbers(str)for boths1ands2to get lists of their valid number representations,list1andlist2. - The
generateValidNumbers(str)function works as follows:- It checks if
stritself is a valid integer (no leading zeros unless it's just "0"). If so, addstrto its results. - It then iterates through all possible decimal point positions in
str. For each split into an integer partint_partand a fractional partfrac_part:- It checks if
int_partis a valid integer part (no leading zeros unless it's "0"). - It checks if
frac_partis a valid fractional part (no trailing zeros). - If both are valid, it combines them as
"int_part.frac_part"and adds to its results.
- It checks if
- It returns the list of valid representations.
- It checks if
- After getting
list1andlist2, iterate through all pairs(x, y)wherexis inlist1andyis inlist2. - For each pair, format it as
"(x, y)"and add it to theresultlist. - Return
result.
Walkthrough
First, we remove the outer parentheses from the input string s to get a string of digits.
We then iterate through all possible split points of this digit string. A split divides the string into two non-empty substrings, s1 and s2.
For each substring (s1 and s2), we find all the ways it can be interpreted as a valid number. This is done by a helper function, generateValidNumbers.
The generateValidNumbers function considers two cases for a given digit string t:
- Integer:
tis a valid integer if it's "0" or doesn't start with '0'. - Decimal:
tcan be split into an integer partiand a fractional partf. This is a valid decimal ifiis a valid integer andfdoes not end with '0'. The function tries all possible positions for the decimal point. The helper function returns a list of all valid string representations fors1ands2. We then take the Cartesian product of these two lists. Each pair(x, y)is formatted into the string"(x, y)"and added to our final answer list. The code snippet below illustrates this logic.
class Solution { public List<String> ambiguousCoordinates(String s) { List<String> result = new ArrayList<>(); String digits = s.substring(1, s.length() - 1); int n = digits.length(); for (int i = 1; i < n; i++) { String s1 = digits.substring(0, i); String s2 = digits.substring(i); List<String> list1 = generateValidNumbers(s1); List<String> list2 = generateValidNumbers(s2); if (!list1.isEmpty() && !list2.isEmpty()) { for (String x : list1) { for (String y : list2) { result.add("(" + x + ", " + y + ")"); } } } } return result; } private List<String> generateValidNumbers(String t) { List<String> res = new ArrayList<>(); int n = t.length(); if (n == 0) { return res; } // Case 1: Integer if (isValidInteger(t)) { res.add(t); } // Case 2: Decimal for (int i = 1; i < n; i++) { String intPart = t.substring(0, i); String fracPart = t.substring(i); if (isValidInteger(intPart) && isValidFractional(fracPart)) { res.add(intPart + "." + fracPart); } } return res; } private boolean isValidInteger(String s) { // Not a valid integer if it has a leading zero (and is not "0") return s.length() <= 1 || s.charAt(0) != '0'; } private boolean isValidFractional(String s) { // Not a valid fractional part if it has a trailing zero return s.charAt(s.length() - 1) != '0'; }}Complexity
Time
O(N^4), where N is the length of the digit string. The main loop runs N-1 times. Inside, generating possibilities for a substring of length k takes O(k^2). Combining results from two lists of size O(i) and O(N-i) takes O(i * (N-i) * N) time. The total time is dominated by this combination step, summing to O(N^4).
Space
O(N^4), where N is the length of the digit string. The output list can contain O(N^3) coordinate strings, each of length O(N).
Trade-offs
Pros
It's a straightforward and easy-to-understand implementation that correctly covers all cases.
The logic directly translates the problem statement into code.
Cons
It can be inefficient for inputs where the same substring is processed multiple times in different splits (e.g., in
(1212)).The time and space complexity are polynomial of a high degree, which might be a concern for larger constraints, though it's acceptable for this problem.
Solutions
Solution
class Solution {public List<String> ambiguousCoordinates(String s) { int n = s.length(); List<String> ans = new ArrayList<>(); for (int i = 2; i < n - 1; ++i) { for (String x : f(s, 1, i)) { for (String y : f(s, i, n - 1)) { ans.add(String.format("(%s, %s)", x, y)); } } } return ans; }private List<String> f(String s, int i, int j) { List<String> res = new ArrayList<>(); for (int k = 1; k <= j - i; ++k) { String l = s.substring(i, i + k); String r = s.substring(i + k, j); boolean ok = ("0".equals(l) || !l.startsWith("0")) && !r.endsWith("0"); if (ok) { res.add(l + (k < j - i ? "." : "") + r); } } return res; }}Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.