这个问题是尝试:
给定一个字符串,找到没有的最长子字符串的长度 重复人物。
示例:
鉴于“nfpdmpi”,答案是“nfpdm”,长度为5。
我的代码是:
int lengthOfLongestSubstring(string s) {
unordered_set<char> sub;
size_t max_len = 0;
for (int i=0 ; i<s.size() ; ++i) {
if ( sub.find(s[i]) != sub.end() ) {
max_len = ( sub.size() > max_len ? sub.size() : max_len );
sub.erase( sub.find(s[i]), sub.end() );
}
sub.insert(s[i]);
}
return ( sub.size() > max_len ? sub.size() : max_len );
}
对于给定的字符串"nfpdmpi"
,我可以在本地PC上获得正确的输出= 5
。
但我将代码提交到LeetCode网站,它说我的输出是6
。
出了什么问题?
答案 0 :(得分:0)
这一行:
sub.erase( sub.find(s[i]), sub.end() );
从无序集中删除范围。由于未定义订单,因此可以删除任意数量的元素,仅包括一个元素。这可能是结果不同的原因。 相反,你想做
sub.clear();
因为你想开始识别一个全新的子字符串。
修改强>
这不是一个正确的解决方案。这是一个带有自定义比较器的有序集:
struct char_occurrence_comp {
static int lastpos[255];
bool operator() (const char& lhs, const char& rhs) {
return lastpos[static_cast<int>(lhs)] < lastpos[static_cast<int>(rhs)];
}
};
int char_occurrence_comp::lastpos[255] = {}; // initialize with 0
int lengthOfLongestSubstring(const std::string& s) {
std::set<char, char_occurrence_comp> sub;
std::size_t max_len = 0;
for (std::size_t i = 0; i < s.size(); ++i) {
const auto iter = sub.find(s[i]);
if ( iter != sub.end() ) {
max_len = std::max(max_len, sub.size());
// end is exclusive, so we need to advance the iterator.
sub.erase(sub.begin(), std::next(iter, 1));
}
// make sure we do not hit the default value (0)
char_occurrence_comp::lastpos[static_cast<int>(s[i])] = i + 1;
sub.insert(s[i]);
}
return std::max(max_len, sub.size());
}
编辑2 :修正了从开始到找到的字符而不是从找到的字符到结尾擦除的擦除行。