Objective c 如何在O(1)中完成此操作
我刚从一家公司得到这个面试测试,我轻松地完成了它,但他们说我的功能处于o(n)状态。问题来了 使用以下方法编写一个类IntegerTracker: 确保每个方法(包括跟踪)在恒定时间内运行(O(1)时间复杂度) 我就是这样完成的Objective c 如何在O(1)中完成此操作,objective-c,big-o,little-o,Objective C,Big O,Little O,我刚从一家公司得到这个面试测试,我轻松地完成了它,但他们说我的功能处于o(n)状态。问题来了 使用以下方法编写一个类IntegerTracker: 确保每个方法(包括跟踪)在恒定时间内运行(O(1)时间复杂度) 我就是这样完成的 - (instancetype)init{ if(self == [super init]){ self.numbers = [[NSMutableArray alloc]init]; } return self; } - (v
- (instancetype)init{
if(self == [super init]){
self.numbers = [[NSMutableArray alloc]init];
}
return self;
}
- (void)trackInt:(int)number{
[self.numbers addObject:[NSNumber numberWithInt:number]];
}
- (int)getMax{
NSNumber *max = [self.numbers valueForKeyPath:@"@max.self"];
return [max intValue];
}
- (int)getMin{
NSNumber *min = [self.numbers valueForKeyPath:@"@min.self"];
return [min intValue];
}
- (float)getMean{
NSNumber *average = [self.numbers valueForKeyPath:@"@avg.self"];
return [average floatValue];
}
- (int)getMode{
int maxCount = 0;
int value = 0;
NSMutableDictionary *mode = [[NSMutableDictionary alloc]init];
for(NSNumber *n in self.numbers){
int currentCount = [[mode objectForKey:n.stringValue]intValue];
currentCount++;
[mode setObject:@(currentCount) forKey:n.stringValue];
if(maxCount < currentCount){
maxCount = currentCount;
value = [n intValue];
}
}
return value;
}
-(instancetype)初始化{
if(self==[super init]){
self.numbers=[[NSMutableArray alloc]init];
}
回归自我;
}
-(void)trackInt:(int)编号{
[self.numbers addObject:[NSNumber numberwhithint:number]];
}
-(int)getMax{
NSNumber*max=[self.numbers valueForKeyPath:@“@max.self”];
返回[max intValue];
}
-(int)getMin{
NSNumber*min=[self.numbers valueForKeyPath:@“@min.self”];
返回[min intValue];
}
-(浮动)getMean{
NSNumber*average=[self.numbers valueForKeyPath:@“@avg.self”];
返回[平均浮动值];
}
-(int)getMode{
int maxCount=0;
int值=0;
NSMutableDictionary*模式=[[NSMutableDictionary alloc]init];
for(自编号中的NSNumber*n){
int currentCount=[[mode objectForKey:n.stringValue]intValue];
currentCount++;
[mode setObject:@(currentCount)forKey:n.stringValue];
如果(最大计数<当前计数){
maxCount=当前计数;
值=[n intValue];
}
}
返回值;
}
有人能告诉我应该如何在O(1)中完成这项工作吗。因为这个原因我已经不及格了,所以不要以为你会给我面试的答案。我不打算在那里工作。我只是想看看如何在不遍历数组的情况下解决这个问题。我假设您必须以不同的方式编写
trackInt:
:
- (void)trackInt:(int)number{
if (number > self.max) {
self.max = number;
}
// different logic for the other desired outcomes
}
这样,每当添加一个新数字时,您就可以进行简单的计算,以确定恒定时间内的max
(以及其他值)
实际的max
方法如下所示:
- (int) getMax { return self.max; }
模式、平均值等的增量计算逻辑看起来有点不同,但您可能永远不必使用数字
数组,但更可能的情况是要跟踪计数
和总和
对于
模式
您可以保留一个字典,将数字
映射到一个计数器上,以跟踪该数字出现的频率。此外,您还存储发生次数最多的当前计数,maxNumberCount
。如果新增加的计数器大于存储的计数器,则您有一个新的模式
值,当前的数字
将存储/返回并相应地更改maxNumberCount
。使函数在O(1)中工作意味着它们内部不能有任何迭代。实际上没有理由实际存储这些数字。您只需存储统计信息:
@property (nonatomic) NSInteger min;
@property (nonatomic) NSInteger max;
@property (nonatomic) NSInteger sum;
@property (nonatomic) NSInteger count;
@property (nonatomic) NSCountedSet *numberCounts; // must be initialized in `init`
@property (nonatomic) NSInteger mostFrequentNumber;
- (void)track:(NSInteger)number {
if (self.count == 0) {
self.min = number;
self.max = number;
self.sum = number;
self.count = 1;
[self.numberCounts addObject:@(number)];
self.mostFrequentNumber = number;
} else {
self.min = MIN(number, self.min);
self.max = MAX(number, self.max);
self.sum += number;
self.count += 1;
[self.numberCounts addObject:@(number)];
if ([self.numberCounts countForObject:@(number)] > [self.numberCounts countForObject:@(self.mostFrequentNumber)] {
self.mostFrequentNumber = number;
}
}
}
- (float)getMean {
if (self.count == 0) { // protection against dividing by zero!
return 0;
}
return ((float) self.sum) / self.count;
}
- (NSInteger)getMode {
return self.mostFrequentNumber;
}
添加了使用NSCountedSet
的模式计算演示NSCountedSet
可以使用其他语言中的字典/映射进行模拟(在一般情况下,我们必须使用带有O(1)操作的结构)。唯一的技巧是在添加时执行必要的操作
另外请注意,当前函数不遵循Obj-C命名约定,这在面试中也应该很重要。每当调用track
时,您可能必须重新计算最大值(以及其他值),如果新数字大于当前最大值,则更改最大值,否则不要更改最大值,等等。不,你不明白他们在问什么。他们希望我完成O(1)中的所有函数。在固定时间内。我不知道该怎么做。所有功能都需要在O(1)中完成。我在O(N)里做的。那么你怎么能在O(1)中完成它们呢?没有关系,但我不知道为什么你使用stringValue
,而n
(这是一个NSNumber
)应该足以满足字典的键。我必须在不到一个小时的时间内完成这项工作,而且它说我不能使用那里的NSNumber作为键。我知道我以前用过一个NSNUjmber作为密钥,但由于某种原因,它在OBJective C中给了我一个错误。这是一家公司为OBJective-C招聘人员,并分发了一个带有方法名称的规范,如get_max()
?看起来你可能躲过了噩梦…@Esko918你在哪里挣扎?对于min
你做的基本上是一样的,对于avg
你存储它们的总和和计数,对于mode
你可以存储一个字典,它以number
作为键,数字出现的次数作为值。@Esko918我不想进一步争辩,我写的段落是O(1),没有迭代发生,只需按固定时间的键进行常规访问。对于平均值,您只需保持一个运行平均值和一个计数。第一首曲目发送一个数字。所以平均值是这个数字,计数是一。对于任何其他你做的((avg*count)+newInt)/(count+1)就是O(1)@Fogmeister,我个人不喜欢(avg*count)的想法,因为这有可能会失去精度-这取决于可能需要的要求(如果sum>intMaxValue)。@chux我不确定,但通常字典访问O(1)iirc,除非你们遇到最坏的情况,它将是O(n)。无论如何,没有要求它不能有一个包含40亿条目的表(或者不管您希望有多少条)。我不认为有一种方法永远是O(1),即使在最坏的情况下也是如此。请注意,该要求甚至没有说明时间复杂度是最佳、最差还是平均情况。那么您将如何获得该模式,但我可以用任何语言来实现这一点。那么,一种没有NSCountedSet的语言呢。我选择Objective-C是因为那是我申请的职位for@Esko918关于NSCountedSet
我错了。我想这不会有什么帮助的。还有,这算什么?如果我给你数字1,4,3,1,1,5,4你怎么计算
@property (nonatomic) NSInteger min;
@property (nonatomic) NSInteger max;
@property (nonatomic) NSInteger sum;
@property (nonatomic) NSInteger count;
@property (nonatomic) NSCountedSet *numberCounts; // must be initialized in `init`
@property (nonatomic) NSInteger mostFrequentNumber;
- (void)track:(NSInteger)number {
if (self.count == 0) {
self.min = number;
self.max = number;
self.sum = number;
self.count = 1;
[self.numberCounts addObject:@(number)];
self.mostFrequentNumber = number;
} else {
self.min = MIN(number, self.min);
self.max = MAX(number, self.max);
self.sum += number;
self.count += 1;
[self.numberCounts addObject:@(number)];
if ([self.numberCounts countForObject:@(number)] > [self.numberCounts countForObject:@(self.mostFrequentNumber)] {
self.mostFrequentNumber = number;
}
}
}
- (float)getMean {
if (self.count == 0) { // protection against dividing by zero!
return 0;
}
return ((float) self.sum) / self.count;
}
- (NSInteger)getMode {
return self.mostFrequentNumber;
}