我想知道这个问题的最佳或最合适的方法:给出一个数字列表示例[2,3,4,2,3],返回仅出现一次的第一个数字清单。
我已经遵循了一些算法方法并提出了这个方法,但不确定Objective-C中是否有任何内置的辅助函数可以让我以更好的性能执行此操作。
如果没有内置解决方案,是否可以对我的方法或任何其他可能在性能方面更好的解决方案进行任何改进?
这是我更新的解决方案:
进行测试:
#import "NSArray+Addons.h"
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray<NSNumber *> *array = @[@(2), @(7), @(3), @(2), @(3), @(2), @(7), @(3), @(2), @(3), @(4), @(7), @(5), @(5), @(9)];
NSLog(@"Unique number: %@", [array firstUniqueNumber]);
}
@end
NSArray类别:
#import "NSArray+Addons.h"
#import "NSMutableDictionary+Addons.h"
@implementation NSArray (Addons)
- (NSNumber *)firstUniqueNumber
{
if (!self.count)
{
return nil;
}
NSMutableDictionary<NSNumber *, NSNumber *> *myUniqueNumbers = [[NSMutableDictionary alloc] init];
return [myUniqueNumbers uniqueValueFromArray:self];
}
@end
NSMutableDictionary类别:
#import "NSMutableDictionary+Addons.h"
@implementation NSMutableDictionary (Addons)
- (NSNumber *)uniqueValueFromArray:(NSArray<NSNumber *> *)array
{
if (!array.count)
{
return nil;
}
for (NSNumber *number in array)
{
if (!self[number])
{
self[number] = [NSNumber numberWithInteger:1];
}
else
{
NSInteger count = [self[number] integerValue];
count++;
self[number] = [NSNumber numberWithInteger:count];
}
}
return [self uniqueNumberWithArray:array];
}
- (NSNumber *)uniqueNumberWithArray:(NSArray<NSNumber *> *)array
{
if (!array.count)
{
return nil;
}
NSNumber *uniqueNumber = nil;
for (NSInteger index = array.count - 1; index > 0; index--)
{
NSNumber *key = array[index];
if (self[key] && [self[key] integerValue] == 1)
{
uniqueNumber = key;
}
}
return uniqueNumber;
}
@end
答案 0 :(得分:4)
NSCountedSet* set = [[NSCountedSet alloc] initWithArray:array];
NSUInteger index = [array indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){
return [set countForObject:obj] == 1;
}];
return index == NSNotFound ? nil : [array objectAtIndex:index];
答案 1 :(得分:1)
此问题可以减少到element distinctness problem,因此没有使用散列和额外空间的线性时间解决方案。
O(n)时间平均+空间的一个简单解决方案是:
伪代码:
map = new hashmap
for each element x:
if map contains x is a key:
map.put(x,map.get(x)+1)
else:
map.put(x,1)
for each element x in array:
if map.get(x) == 1:
return x
//if reached here - no distinct element
示例:强>
array = [2, 3, 4, 2, 3]
create histogram: {[2=2] [3=2], [4=1]}
iterate the array:
check 2, it has value of 2 in histogram. continue
check 3, it has value of 2 in histogram. continue
check 4, it has value of 1 in histogram. Return it and finish.
答案 2 :(得分:0)
-(NSNumber *)returnFirstUniqueFromArray: (NSArray *)array{
//put the numbers in a set
NSCountedSet *numbers = [[NSCountedSet alloc] initWithArray:array];
for(NSNumber *number in array){
//if it only occurs once return
if([numbers countForObject:number]==1) return number;
}
return nil;
}
他们关键在这里你需要一个很好的方法来跟踪事情的发生次数,所以利用NSCountedSet的“计数”方法。会告诉你物体发生了多少次。