查找不适用于 c++ 中特定测试用例的最长子字符串
Find longest substring not working for a particular test case in c++
Q( 不带重复字符的最长子字符串
给定"abcabcbb",答案是"abc",长度为3。
给定"bbbbb",答案是"b",长度为 1。
给定"pwwkew",答案是"wke",长度为3。请注意,答案必须是子字符串,"pwke"是子序列而不是子字符串。
我的回答:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int count[256];
int dummy=0;
int c=0;
for(int i=0;i<256;i++){
count[i]=0;
}
for(int i=0;i<s.length();i++){
count[s[i]]++;
if(count[s[i]]==1){
c++;
i++;
//cout<<c;
}
else{
//cout<<C;
dummy=dummy>c?dummy:c;
//cout<<dummy;
c=0;
for(int j=0;j<256;j++){
count[j]=0;
}
i++;
}
}
return dummy;
}
};
我知道这不是一个最佳解决方案,但我是一个菜鸟。这段代码适用于很多测试用例,除了字符串"pwwkew",它的原始答案是 3,但我得到 0。
我尝试过的:
对于字符串"abcabcbb"
我得到正确的输出,即 3。
对于字符串"bbbb"
我得到正确的输出,即 1。
对于特定的字符串"pwwkew"
我将其设为 0。在这种情况下,答案应该是 3。
我尝试打印值以检查我出错的地方。对于第三种情况,它似乎没有进入else
语句。cout
语句中打印123
.但它应该为pw
打印12
. else 语句中的cout
不起作用。
为什么只有在这种情况下我得到错误的输出?
请帮我解决这个问题。
我相信OP的算法有问题(或至少缺失(。
我并不完全理解算法,但至少在一定程度上计算了字符的出现。如果未1
特定字符的count
,则会找到重复count
并完全重置数组。恕我直言,这是错误的观点。count
数组退化为标志数组(这还不够(。
反例pwwkwe
:
- 在
s[2]
复制 - 重置
count
(即重新启动( - 在
s[4]
复制 - 重置
count
(即重新启动(。
因此,检测到的最长子字符串的长度最多为 2。但从k
开始,它实际上是3(kwe
(。
所以,我想出了一个不同的想法:
一旦发现重复项,最长的子字符串实际上可能刚好开始于此字符的先前出现之后。考虑到这一点,重复不再是重复
。这听起来可能有点令人困惑。也许,当我展示我是如何解决它的时,它变得更容易理解:
count
不再用作标志数组。相反,上次出现的索引存储在那里(对于每个字符(。因此,对于每个字符,可以检查到其先前出现的距离(该字符没有重复项(。但是,它必须没有任何重复项。因此,我另外引入了一个起始索引(i0
(,它总是在字符的先前出现之后设置一次。(不考虑启动索引之前的重复项。这样,在确定正确的子字符串时,只考虑最后一个重复项。
在代码中:
#include <iostream>
#include <string>
/* determines longest substring without duplicated characters.
* param s ... string to evaluate
* return: pair of
* first ... start index of found substring
* second ... length of found substring
*/
std::pair<int, int> lengthOfLongestSubstring(const std::string &s)
{
// index of last occurrence for each character
// (-1 ... character not yet occurred)
int iChrLast[256];
for (int &i : iChrLast) i = -1;
// result start index, length
std::pair<int, int> result(0, 0);
// check all characters (i0 ... current start)
for (int i = 0, i0 = 0; i < (int)s.length(); ++i) {
// cast char to index (via (unsigned char) to prevent negative indices)
const int c = (unsigned char)s[i];
// check if there is a duplicate after current start
if (iChrLast[c] >= i0) i0 = iChrLast[c] + 1;
// compute length with current start
const int len = i - i0 + 1;
// check whether new max. length found (update in case)
if (result.second < len) result = std::make_pair(i0, len);
// remember last occurrence of this char
iChrLast[c] = i;
}
// done
return result;
}
int main()
{
const std::string tests[] = {
"abcabcbb",
"bbbbb",
"pwwkew"
};
for (const std::string &test : tests) {
const std::pair<int, int> result = lengthOfLongestSubstring(test);
std::cout << test << ": " << result.first << ", " << result.second
<< " ("<< test.substr(result.first, result.second) << ")n";
}
return 0;
}
输出:
abcabcbb: 0, 3 (abc)
bbbbb: 0, 1 (b)
pwwkew: 2, 3 (wke)
科里鲁的现场演示
我不得不承认,我同意克雷格·杨的观点
编程不是要学习"不重复"的错误。这是关于了解正在进行的状态变化,因果关系,并弄清楚何时和为什么它没有按照您的预期进行。
我试图解决这个问题(作为一个难题(,假设某种回溯甚至递归是必要的。所以,当我终于找到这个解决方案时,我自己有点惊讶。(一旦我让它运行,我就忍不住把它作为答案发布。
你如何学习制作算法?也许是,天赋,也许是,经验,肯定还有很多练习......
- pybind11 运行测试用例
- GTest,仅参数化测试用例
- 如何使用不同的谷歌模拟运行相同的谷歌测试用例?
- 请找出我的代码中的错误,它在提交得到错误答案的同时仍然适用于我的所有测试用例
- 如何使用值模板编写文档测试用例?
- 用于查找最低共同祖先的代码不适用于某些测试用例
- 为什么给定的代码不适用于所有测试用例?为什么当输入为 7786 时它不起作用?
- GTest - 在不同的参数上运行多个测试用例
- 如何创建演示 /EH 成本的最小测试用例?
- 查找在 4 和问题中代码失败的测试用例
- 如何编写在函数执行过程中垃圾回收的测试用例?
- 括号检查器完美地适用于单个测试用例,但对于所有测试用例,它给出了分段错误?
- 我已经通过了该问题的所有测试用例,甚至是Udebugg上的所有测试用例,并且仍然在UVA在线法官上获得了WA裁决
- 如何使用参数化测试用例
- 相同的测试用例,但代码块和Ideone的输出不同
- 在老板层次结构中查找"top"老板仅适用于某些测试用例
- Eclipse 项目中的 OSCPack 外部库测试用例
- 每次使用不同的fixture多次执行一个测试用例
- 在BOOST test中添加测试套件而不是测试用例
- 如何在谷歌代码堵塞中输入c++代码中的测试用例