C++ LeetCode问题3:没有重复字符的最长子字符串

C++ LeetCode问题3:没有重复字符的最长子字符串,c++,substring,string-length,C++,Substring,String Length,此问题是为了尝试: 给定一个字符串,查找不带 重复字符 举个例子: 给定“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

此问题是为了尝试:

给定一个字符串,查找不带 重复字符

举个例子:

给定“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 );
}
int lengthOfLongestSubstring(字符串s){
无序集子;
尺寸最大长度=0;
对于(int i=0;i max_len?sub.size():max_len);
sub.erase(sub.find(s[i]),sub.end());
}
子条款插入(s[i]);
}
返回(子大小()>最大长度?子大小():最大长度);
}
对于给定的字符串“nfpdmpi”,我可以在本地PC上获得正确的输出=
5

但是我把代码提交到LeetCode网站上,它说我的输出是
6

怎么了?

这行:

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());
}
struct char\u occurrence\u comp{
静态int-lastpos[255];
布尔运算符()(常量字符和lhs、常量字符和rhs){
返回lastpos[静态施法(lhs)]

编辑2:修复了从开始到找到的字符而不是从找到的字符到结束进行擦除的擦除行。

但是我将代码提交到LeetCode网站——然后调试代码,或者向“LeetCode”投诉。另外,
max_len=std::max(max_len,sub.size())
可以替换这个:
max_len=(sub.size())>max_len?sub.size():max_len)
那么,由于未定义顺序,使用无序的集合::erase()是否有危险?关键是,它有未定义的语义。但是我刚刚意识到我的修正是不正确的,因为它不会在第一次出现重复字符后计算字符数。您必须使用
set
Compare
参数,该参数按输入顺序排序。@flyx但我刚刚意识到我的修复不正确,因为它不会在第一次出现重复字符后计算字符数。-我不认为你用来解决这个问题的所有代码都是必要的@PaulMcKenzie反例:应该返回5,返回3。aa我的代码也失败了,因为我没有仔细考虑,将进行另一次编辑。