查找数组中的最大差异 - 需要算法解决方案优化 [重复]

Posted

技术标签:

【中文标题】查找数组中的最大差异 - 需要算法解决方案优化 [重复]【英文标题】:Find Max Difference in Array - Need Algorithm Solution Optimization [duplicate] 【发布时间】:2017-04-17 01:52:14 【问题描述】:

我在HackerRank - Max Difference 上练习求解算法。

问题如下:

给定一个包含 n 个元素的数组:d[ 0 ], d[ 1 ], ..., d[n-1]。计算所有连续子数组最大差的总和(S)。

正式地:

S = summaxd[l,...,r] - mind[l, ..., r,∀ 0 <= l <= r < n 

输入格式:

n
d[0] d[1] ... d[n-1]

输出格式:

S

示例输入:

4
1 3 2 4

样本输出:

12

说明:

l = 0; r = 0;
array: [1]
sum = max([1]) - min([1]) = 0

l = 0; r = 1;
array: [1,3]
sum = max([1,3]) - min([1,3]) = 3 - 1 = 2

l = 0; r = 2;
array: [1,3,2]
sum = max([1,3,2]) - min([1,3,2]) = 3 - 1 = 2

l = 0;r = 3;
array: [1,3,2,4]
sum = max([1,3,2,4]) - min([1,3,2,4]) = 4 - 1 = 3

l = 1; r = 1 will result in zero

l = 1; r = 2;
array: [3,2]
sum = max([3,2]) - min([3,2]) = 3 - 2 = 1;

l = 1; r = 3;
array: [3,2,4]
sum = max ([3,2,4]) - min([3,2,4]) = 4 - 2 = 2;

l = 2; r = 2; will result in zero

l = 2; r = 3;
array:[2,4]
sum = max([2,4]) - min([2,4]) = 4 -2 = 2;

l = 3; r = 3 will result in zero;

Total sum = 12

这是我的解决方案:

-(NSNumber*)sum:(NSArray*) arr 

int diff = 0;
int curr_sum = diff;
int max_sum = curr_sum;

for(int i=0; i<arr.count; i++)

    for(int j=i; j<=arr.count; j++) 
        // Calculate current diff
        if (!(j-i > 1)) 
            continue;
        

        NSArray *array = [arr subarrayWithRange:NSMakeRange(i, j-i)];
        if (!array.count || array.count == 1) 
            continue;
        
        int xmax = -32000;
        int xmin = 32000;
        for (NSNumber *num in array) 
            int x = num.intValue;
            if (x < xmin) xmin = x;
            if (x > xmax) xmax = x;
        
        diff = xmax-xmin;

        // Calculate current sum
        if (curr_sum > 0)
           curr_sum += diff;
        else
           curr_sum = diff;

        // Update max sum, if needed
        if (curr_sum > max_sum)
           max_sum = curr_sum;   
    


return @(max_sum);


总共有 10 个测试用例。 上述解决方案通过了前 5 个测试用例,但没有通过其他 5 个测试用例,由于超时(>=2s)而失败。

“这里是状态:由于超时而终止”。

请帮助我了解如何进一步优化此代码。

谢谢!

【问题讨论】:

猜猜:你不需要改进的代码——你需要更好的算法。 是的。有什么建议吗? Any suggestions? 很多。对于n = 1,解决方案是微不足道的。解决方案如何改变添加一个元素?完全(?)不同的角度:maxdiff 对于每个子数组都是相同的,except 不包括 min 和/或 max。 问题/解决方案期望 n>=2。我认为“每个子数组的 maxdiff 都是相同的”句子是有道理的。在这条线上思考。 添加一个元素会如何改变解决方案?部分最近流行:DP。) 【参考方案1】:

Python 中已经有一个answer。这是我的 Objective C 版本:

@interface Stack : NSObject 
    NSMutableArray* m_array;
    int count;

- (void)push:(id)anObject;
- (id)pop;
- (id)prev_prev;
- (void)clear;
@property (nonatomic, readonly) NSMutableArray* m_array;
@property (nonatomic, readonly) int count;
@end

@implementation Stack
@synthesize m_array, count;
- (id)init

    if( self=[super init] )
    
        m_array = [[NSMutableArray alloc] init];
        count = 0;
    
    return self;

- (void)push:(id)anObject

    [m_array addObject:anObject];
    count = m_array.count;

- (id)pop

    id obj = nil;
    if(m_array.count > 0)
    
        obj = [m_array lastObject];
        [m_array removeLastObject];
        count = m_array.count;
    
    return obj;

- (id)prev_prev

    id obj = nil;
    if(m_array.count > 0)
    
        obj = [m_array lastObject];
    
    return obj;

- (void)clear

    [m_array removeAllObjects];
    count = 0;

@end

@interface SolutionClass:NSObject
/* method declaration */
-(NSNumber*)findDiff:(NSArray*) arr;
@end


@implementation SolutionClass
-(NSNumber*)findDiff:(NSArray*) arr 
    NSNumber *maxims = [self sum:arr negative:NO];
    NSNumber *minims = [self sum:arr negative:YES];
    NSNumber *diff = @(maxims.longLongValue+minims.longLongValue);
    NSLog(@"diff: %@", diff);
    return diff;


-(NSNumber*)sum:(NSArray*) arr negative:(BOOL)negate 
    Stack *stack = [Stack new];
    [stack push:@@(-1): [NSNull null]];
    long long sum = 0;

    for(int i=0; i<arr.count; i++) 
        NSNumber *num = arr[i];
        if (negate) 
            num = @(-num.longLongValue);
        

        NSDictionary *prev = stack.m_array.lastObject;
        NSNumber *prev_i = (NSNumber*)prev.allKeys[0];
        NSNumber *prev_x = (NSNumber*)prev.allValues[0];

        if ([self isNumber:prev_x]) 
            while (num.longLongValue > prev_x.longLongValue) 
                prev_i = (NSNumber*)prev.allKeys[0];
                prev_x = (NSNumber*)prev.allValues[0];
                prev = [stack pop];
                NSDictionary *prev_prev_Dict = [stack prev_prev];
                NSNumber *prev_prev_i = (NSNumber*)prev_prev_Dict.allKeys[0];

                sum += prev_x.longLongValue * (i-prev_i.longLongValue) * (prev_i.longLongValue - prev_prev_i.longLongValue);

                prev = stack.m_array.lastObject;
                prev_x = (NSNumber*)prev.allValues[0];
                if (![self isNumber:prev_x]) 
                    break;
                

            
        
        [stack push:@@(i): num];
    
    NSLog(@"Middle: sum: %lld", sum);

    while (stack.count > 1) 
        NSDictionary *prev = [stack pop];
        NSDictionary *prev_prev_Dict = [stack prev_prev];

        NSNumber *prev_i = (NSNumber*)prev.allKeys[0];
        NSNumber *prev_x = (NSNumber*)prev.allValues[0];
        NSNumber *prev_prev_i = (NSNumber*)prev_prev_Dict.allKeys[0];

        sum += prev_x.longLongValue * (arr.count-prev_i.longLongValue) * (prev_i.longLongValue - prev_prev_i.longLongValue);

        prev = stack.m_array.lastObject;
        prev_x = (NSNumber*)prev.allValues[0];
        if (![self isNumber:prev_x]) 
            break;
        
    
    NSLog(@"End: sum: %lld", sum);

    return @(sum);


-(BOOL)isNumber:(id)obj 
    if ([obj isKindOfClass:[NSNumber class]]) 
        return 1;
    
    return 0;

@end

上述解决方案适用于 7 个测试用例,但其他 3 个测试用例失败:“状态:错误答案”。希望也能找到解决办法。

编辑:

已更新通过所有测试用例的 WORKING 代码。之前使用了错误的数据类型。

【讨论】:

你试过python代码吗?我在思考 numerical limit,对 Objective CNSNumber 几乎一无所知。

以上是关于查找数组中的最大差异 - 需要算法解决方案优化 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

ArrayIndexOutOfBoundsException,同时找到数组中两个连续元素之间的最大差异

使用数组查找最大差异

元素中最大距离的算法

使用 STL 算法在表(向量的向量、二维数组)中查找最小值/最大值的优雅方法

经典算法详解(11)递归查找数组中的最大值

漫画算法22计数排序的优化