模糊坐标

94 阅读1分钟

这是我参与「掘金日新计划 · 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, 000100.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];
};

说在后面

本人为算法业余爱好者,平时只是随着兴趣偶尔刷刷题,如果上面分享有错误的地方,欢迎指出,感激不尽。