我的代码看起来很完美,但显示错误的输出。有人可以帮我我在这里做错了啥吗?
Posted
技术标签:
【中文标题】我的代码看起来很完美,但显示错误的输出。有人可以帮我我在这里做错了啥吗?【英文标题】:my code seems perfect but showing wrong output. can someone help me what wrong am i doing here?我的代码看起来很完美,但显示错误的输出。有人可以帮我我在这里做错了什么吗? 【发布时间】:2021-09-15 06:20:37 【问题描述】:我必须返回数组中连续 seq 的最大 len。 考虑这个例子:-
N = 7
a[] = 2,6,1,9,4,5,3
我的代码应该返回 6,但它给出 1。不知道怎么做?
int findLongestConseqSubseq(int arr[], int N)
//Your code here
unordered_map<int,int> mp;
int ans=0;
for(int i=0;i<N;i++)
if(mp.count(arr[i])>0)
continue;
int len1=mp[arr[i]-1];
int len2=mp[arr[i]+1];
int ns=len1+len2+1;
ans=max(ans,ns);
mp[arr[i]-len1]=ns;
mp[arr[i]+len2]=ns;
// ans=max(ans,ns);
return ans;
【问题讨论】:
你能解释一下为什么你的代码应该返回正确的结果吗?它不是那么明显。我也不明白为什么您的示例输入的正确结果应该是 6 我花了一点时间来理解这个问题 - 它要求获取加扰数组中最大数量的连续数字并将其返回。例如,如果我的数组有数字 [9,0,1,2,3,6,8],那将是 [0,1,2,3] 或 4 个连续数字。 代码没有说明它要完成什么,但标识符中的拼写错误似乎并不完美。什么是LongestConseq[uent?!]Subseq[uence]
/a consecutive seq[uence]
?
在这种方法中不需要排序,我们必须在 O(N) 中进行。方法是正确的,唯一的问题是地图。
【参考方案1】:
您的实现存在两个问题。
第一个问题是代码:
if(mp.count(arr[i])>0)
continue;
此代码不足以确保重复的数字不会进入循环的其余部分(要了解为什么会这样,请考虑len1
或len2
都不为零时会发生什么。
您可以将其替换为:
if(!mp.insert(pair<int,int>(arr[i], 1)).second)
continue;
如果存在arr[i]
的条目,这将跳过循环的其余部分,但也会确保在计算 if 表达式后存在条目。
第二个问题是代码:
int len1=mp[arr[i]-1];
int len2=mp[arr[i]+1];
C++ 中映射的下标运算符具有创建条目(如果条目不存在)的副作用。这对您的算法来说是有问题的,因为您不希望这种情况发生。如果这样做会导致前一段代码跳过不应该的数字。解决方案是使用find
,但由于此代码有点难看(恕我直言),编写辅助函数可能更简洁:
inline int findOrDefault(const unordered_map<int, int>& map, int key, int defaultValue)
auto find = map.find(key);
return (find == map.end()) ? defaultValue : find->second;
并使用它来更新您的代码:
int len1=findOrDefault(mp, arr[i]-1, 0);
int len2=findOrDefault(mp, arr[i]+1, 0);
将所有这些放在一起,您最终会得到:
inline int findOrDefault(const unordered_map<int, int>& map, int key, int defaultValue)
auto find = map.find(key);
return (find == map.end()) ? defaultValue : find->second;
int findLongestConseqSubseq(int arr[], int N)
unordered_map<int,int> mp;
int ans=0;
for(int i=0;i<N;i++)
if(!mp.insert(pair<int,int>(arr[i], 1)).second)
continue;
int len1=findOrDefault(mp, arr[i]-1, 0);
int len2=findOrDefault(mp, arr[i]+1, 0);
int ns=len1+len2+1;
ans=max(ans,ns);
mp[arr[i]-len1]=ns;
mp[arr[i]+len2]=ns;
return ans;
【讨论】:
非常感谢兄弟,它成功了,我也学到了新东西。非常感谢@idz 别忘了接受答案!它可以防止其他人浪费时间阅读您的问题,却发现它已经得到解答。【参考方案2】:好的,有时间再看一遍,我想出了这个。首先,我们对数组进行排序以使事情变得更容易。然后我们可以一次通过数字,每次下一个连续数字大一时计数。如果排序后下一个数字不是大一,那么我们重置并重新开始计数,将最高的连续计数存储在 max 中。
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
cout << "Get Longest Consecutive Streak: " << endl;
int intArray[] = 9, 1, 2, 3, 4, 6, 8, 11, 12, 13, 14, 15 ,16 ;
int arrayLength = size(intArray);
sort(intArray, intArray + arrayLength); //Sort Array passing in array twice plus amount of indexes in array
cout << "Sorted Array looks like this:" << endl; //Outputting sorted array to check
for (int i = 0; i < arrayLength; i++)
cout << intArray[i] << " ";
cout << endl;
int count = 1;
int max = 1;
/*
* Loop through array, if the next number is one greater than current then add to count
* If it is not, reset the count.
* Store highest count value found passing through.
* */
for (int i = 0; i < arrayLength -1; i++)
if (intArray[i + 1] == intArray[i] + 1) //checking next value - is it equal to this one + 1?
count++;
else //else if it is not, store the value if it is higher that what is currently there, then reset
if (max < count)
max = count;
count = 1;
//Edge case: check again one more time if the current count (when finishing) is greater than any previous
if (max < count)
max = count;
cout << "Longest Consecutive Streak:" << endl;
cout << max << endl;
return 0;
【讨论】:
这是一种完全不同的算法,是 O(n log n),而 OP 发布的算法在正确实施时是 O(n)。 这将是 O(nlogn) 并且不需要在这种方法中排序。以上是关于我的代码看起来很完美,但显示错误的输出。有人可以帮我我在这里做错了啥吗?的主要内容,如果未能解决你的问题,请参考以下文章
我正在使用 gowong/material-sheet-fab 但它显示错误。有人可以帮我吗?