这是我参与「掘金日新计划 · 2 月更文挑战」的第 24 天,点击查看活动详情
问题描述
我们有一些二维坐标,如 "(1, 3)" 或 "(2, 0.5)",然后我们移除所有逗号,小数点和空格,得到一个字符串 S。返回所有可能的原始字符串到一个列表中。
原始的坐标表示法不会存在多余的零,所以不会出现类似于"00", "0.0", "0.00", "1.0", "001", "00.01"或一些其他更小的数来表示坐标。此外,一个小数点前至少存在一个数,所以也不会出现“.1”形式的数字。
最后返回的列表可以是任意顺序的。而且注意返回的两个数字中间(逗号之后)都有一个空格。
示例 1:
输入: "(123)"
输出: ["(1, 23)", "(12, 3)", "(1.2, 3)", "(1, 2.3)"]
示例 2:
输入: "(00011)"
输出: ["(0.001, 1)", "(0, 0.011)"]
解释:
0.0, 00, 0001 或 00.01 是不被允许的。
示例 3:
输入: "(0123)"
输出: ["(0, 123)", "(0, 12.3)", "(0, 1.23)", "(0.1, 23)", "(0.1, 2.3)", "(0.12, 3)"]
示例 4:
输入: "(100)"
输出: [(10, 0)]
解释:
1.0 是不被允许的。
提示:
- 4 <= S.length <= 12.
- S[0] = "(", S[S.length - 1] = ")", 且字符串 S 中的其他元素都是数字。
思路分析
首先我们先要理解一下题目意思,题目会给我们一个字符串,我们需要通过这个字符串推断出其原来可能的所有坐标,坐标的经纬度可以试整数也可以是小数,而且整数部分不能有前导零且小数部分不能以零结尾。
- 分割坐标
因为坐标是由经纬度两部分组成的,所以我们可以先将整个字符串进行划分,从字符串中间的每一个位置进行切割,切割成两部分作为经纬度。
const arr = [];
for (let i = 0; i < s.length - 1; i++) {
arr.push([s.slice(0, i + 1), s.slice(i + 1)]);
}
- 添加小数点
经纬度分割开来之后,我们便可以对经纬度分别添加小数点,枚举每一个位置,判断遍历到的每个位置是否是一个合法的位置,合法则可在那个位置添加上小数点,得到一个新的坐标。避免产生重复数据,我们可以使用set来保存每一个坐标值,最后再解构为数组即可。
遍历过程中只需要判断两点即可:
1、判断小数部分是否以 0 结尾
arr[i][0].endsWith("0");
2、判断是否有前导零
/^0\d/.test(x);
const res = new Set();
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr[i][0].length; j++) {
let x = arr[i][0];
if (j > 0 && !arr[i][0].endsWith("0")) {
x = x.slice(0, j) + "." + x.slice(j);
}
if (/^0\d/.test(x)) continue;
for (let k = 0; k < arr[i][1].length; k++) {
let y = arr[i][1];
if (k > 0 && !arr[i][1].endsWith("0")) {
y = y.slice(0, k) + "." + y.slice(k);
}
if (/^0\d/.test(y)) continue;
res.add("(" + x + ", " + y + ")");
}
}
}
完整 AC 代码如下:
AC 代码
/**
* @param {string} s
* @return {string[]}
*/
var ambiguousCoordinates = function (s) {
s = s.slice(1, -1);
const arr = [];
for (let i = 0; i < s.length - 1; i++) {
arr.push([s.slice(0, i + 1), s.slice(i + 1)]);
}
const res = new Set();
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr[i][0].length; j++) {
let x = arr[i][0];
if (j > 0 && !arr[i][0].endsWith("0")) {
x = x.slice(0, j) + "." + x.slice(j);
}
if (/^0\d/.test(x)) continue;
for (let k = 0; k < arr[i][1].length; k++) {
let y = arr[i][1];
if (k > 0 && !arr[i][1].endsWith("0")) {
y = y.slice(0, k) + "." + y.slice(k);
}
if (/^0\d/.test(y)) continue;
res.add("(" + x + ", " + y + ")");
}
}
}
return [...res];
};
说在后面
本人为算法业余爱好者,平时只是随着兴趣偶尔刷刷题,如果上面分享有错误的地方,欢迎指出,感激不尽。