题干
我们有一些二维坐标,如 "(1, 3)"
或 "(2, 0.5)"
,然后我们移除所有逗号,小数点和空格,得到一个字符串S。返回所有可能的原始字符串到一个列表中。
原始的坐标表示法不会存在多余的零,所以不会出现类似于"00"
, "0.0"
, "0.00"
, "1.0"
, "001"
, "00.01"
或一些其他更小的数来表示坐标。此外,一个小数点前至少存在一个数,所以也不会出现“.1”
形式的数字。
最后返回的列表可以是任意顺序的。而且注意返回的两个数字中间(逗号之后)都有一个空格。
思路
一开始想到的就是DFS,将每次深搜分为以下几种情况:
1、当前坐标是最后一位,那就直接加上)
即可
2、当前坐标不是最后一位
可以尝试放数字到末尾
或是放小数点
或是放逗号
但是发现,放逗号和小数点是有点难处理的(需要细分当前情况是否可以放小数点或是逗号;比如说逗号只能放一个、小数点各一个逗号放一个)
同时发现情况1有一点问题:如果最后的数字是001
,或是1.100
,就还需要额外的处理
因此修改了整体的框架思路:
首先记录当前位置的前一个位置的数字(比如说前面是1.001
,那么此时记录的就是001
;或者说前面记录的是, 002
,那么此时记录的就是002
)
此刻下标j
指向的就是1.001
中的.
,或是, 002
中的
接着,先判断当前坐标是不是最后一位,如果是的话,就根据情况来判断是否要push_back
字符(比如说整数,或是小数部分,是否有多余的0的情况;具体的判断方法见代码)
PS:
注意,这里必须要放入了一个逗号以后,才能放入到ans
中
然后,数字在什么情况下都是可以直接放的
最后:
如果是整数,就需要判断前面是否有多余的0
如果是小数,就要判断后面是否有多余的0,
上述一旦有多余的0,就return
判断完后,再根据情况适当的添加逗号或小数点
PS:
count
的作用是记录逗号的数量,smallpoint
是记录小数点的数量(每次放置了逗号以后,都要重置小数点的数量)
代码:
class Solution {
private:
vector<string> ans{};
void dfs(string &s, string temp, int index, int count, int smallpoint) {
int j = temp.size() - 1;
while (j > 0 && temp[j] != '.' && temp[j] != '(' && temp[j] != ' ') -- j;
if (index == s.size() - 1) {
if (count == 1) {
if (temp[j] == '.' && temp.back() != '0') ans.push_back(temp + ")");
else if (temp[j] == ' ' && (temp[j + 1] != '0' || temp.size() - 2 == j)) ans.push_back(temp + ")");
}
return ;
}
dfs(s, temp + s[index], index + 1, count, smallpoint);
if ((temp[j] == '(' || temp[j] == ' ') && temp[j + 1] == '0' && temp.size() - 2 != j) return ; // 整数部分前面有多余的0
else if (temp[j] == '.' && (temp.back() == '0')) return ; // 小数部分后面有多余的0
if (count == 0 && index > 1 && temp.back() != '.') dfs(s, temp + ", ", index, 1, 0);
if (smallpoint == 0 && temp.back() != ' ' && temp.back() != '(') dfs(s, temp + ".", index, count, 1);
}
public:
vector<string> ambiguousCoordinates(string s) {
dfs(s, "(", 1, 0, 0);
return ans;
}
};
反思
DFS
的状态机雀实是有点不太好处理,并且很多时候都是自己给数据,面向bug
编程….
但总算是写出来了吧
后面看了看题解,发现很多人给出的思路就是:
将字符串中的数字分为两部分,各个部分用小数点隔开并校验合法性
最后来个双循环,用(,)
将结果拼接,再将结果放入ans
中
这种做法coding
上雀实舒服
有点笨比了hhhhhhhhhhhh