我维护一个整数数组。重要的是,此数组中的整数始终是从0开始的顺序。例如,如果数组中有5个整数,则它们的值必须为0,1,2,3,4(尽管以任何顺序排列)。
我想设计一种简单有效的方法来检查这一点。如果数组包含从0到array.count - 1的所有正整数,它将返回true。
我很想听到处理这个问题的一些不同想法!
答案 0 :(得分:3)
或者,给定整数[0..N-1]
如果你依次将2加到2的幂,则总和将为-1+2^N
。这不是任何其他N个整数集的属性。
我提供此选项作为替代方案,不对适用性,性能或效率提出任何要求,并且我认识到当N变大时会出现问题。
答案 1 :(得分:1)
基本上你要测试的是你的数组是[0...n-1]
的排列。对于时间和内存都有O(n)
的简单算法。例如,请参阅此PDF file。
有时我会使用一个非常简单的检查,即O(n)
及时O(1)
和0 + 1 + 2 + ... + n-1 == n * (n-1) / 2
0 + 1² + 2² + ... + (n-1)² == n * (n-1) * (2 * n - 1) / 6
。它理论上可以返回误报,但它是找出大多数错误的好方法。它基于以下事实:
bool IsPermutation(int[] array)
{
long length = array.Length;
long total1 = 0;
long total2 = 0;
for (int i = 0; i<length; i++)
{
total1 += array[i];
total2 += (long)array[i] * array[i];
}
return
2 * total1 == length * (length - 1) &&
6 * total2 == length * (length - 1) * (2 * length - 1);
}
我不知道objective-c,但代码在C#中看起来像这样:
{{1}}
答案 2 :(得分:0)
这是我当前的实现(testSet是一组NSNumbers) -
- (BOOL)itemsSequencedCorrectlyInSet:(NSSet *)testSet{
for (NSInteger i = 0; i < testSet.count; i++) {
if (![testSet containsObject:[NSNumber numberWithInteger:i]]) {
return NO;
}
}
return YES;
}
答案 3 :(得分:0)
这与你的itemsSequencedCorrectlyInSet:方法没什么不同,但是它使用了一个可变的索引集,它比执行更快 - [NSSet containsObject:]。在您拥有数千个表行之前,可能不是问题。无论如何,这里的关键见解是Pigeonhole原则说如果你有N个小于N的整数并且没有重复,那么你每个都只有0 ... N-1一次。
-(BOOL)listIsValid:(NSArray*)list
{
NSMutableIndexSet* seen = [NSMutableIndexSet indexSet];
for ( NSNumber* number in list )
{
NSUInteger n = [number unsignedIntegerValue];
if ( n >= [array count] || [seen containsIndex:n] )
return NO;
[seen addIndex:n];
}
return YES;
}