面試題之判斷數(shù)組中隨機三個數(shù)之和等于一個已知數(shù)--OC代碼實現(xiàn)及優(yōu)化

前言

一日不學習,恐落后于世界久矣。

最近有朋友面試,面試一些簡單的算法,多了不說,總結(jié)如下。

1、判斷整數(shù)數(shù)組中有沒有隨機三個數(shù)之和等于一個已知數(shù)

看到這個題目,我簡單粗暴的想起了三層for循環(huán),需要考慮的是三層for循環(huán)里的數(shù),每層的數(shù)都不能是一樣的,于是寫出了這樣的方法。

- (BOOL)seekRandomThreeElementSum:(NSInteger)sum Arr:(NSArray *)array {
    NSInteger b,c,d,i,j,k;
    for (i = 0; i < array.count; i ++) {
        b = [array[i] integerValue];
        for (j = 0 ; j < array.count; j ++) {
            if (j != i) {//保證外層循環(huán)的數(shù)和本層循環(huán)不一樣
                c = [array[j] integerValue];
                for (k = 0; k < array.count; k ++) {
                    if (k != i && k != j) {//保證外層循環(huán)的數(shù)和本層循環(huán)不一樣
                        d = [array[k] integerValue];
                        if (b + c + d == sum) {
                            NSLog(@"have the sum");
                            return YES;
                        }
                    }
                }
            }
        }
    }
    NSLog(@"have not the sum");
    return NO;
}

但是這樣的話只是取出來的數(shù)雖然無重復,但是每次取出來的數(shù)是有順序的,可能每次取出的都是第0,1,2個元素 但是有可能第一層循環(huán)取出的是0 也可能是1或者2,這樣的話,循環(huán)的次數(shù)就有沒必要的增加,實際上是A(3,N)和C(3,N)的區(qū)別,于是優(yōu)化如下。

- (BOOL)seekRandomThreeElementSum:(NSInteger)sum Arr:(NSArray *)array {
    NSInteger b,c,d,i,j,k;
    for (i = 0; i < array.count - 2; i ++) {//因為是三個數(shù) 所以第一層循環(huán)只用循環(huán)數(shù)組個數(shù)減2的次數(shù)
        b = [array[i] integerValue];
        for (j = i + 1 ; j < array.count - 1; j ++) {
            c = [array[j] integerValue];//在i不變的時候 j一直增加 全走一遍
            for (k = j + 1; k < array.count; k ++) {
                d = [array[k] integerValue];//在I,j不變的時候 k一直增加 全走一遍  
                if (b + c + d == sum) {
                    NSLog(@"have the sum");
                    return YES;
                }
            }
        }
    }
    NSLog(@"have not the sum");
    return NO;
}

但是三層for循環(huán)時間復雜度還是比較大,從網(wǎng)上找了比較好的優(yōu)化方法,思路是先將數(shù)組排序,外層遍歷和上邊的方法一樣,只遍歷count -2次,然后前邊的數(shù)往后趕,后邊的數(shù)往前趕,利用雙指針遍歷,時間復雜度能減少一半,如下:

- (BOOL)seekRandomThreeElementSum1:(NSInteger)sum Arr1:(NSArray *)array {
    NSArray *arr1 = [array sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
        return [obj1 compare:obj2];
    }];//將數(shù)組排序
    NSLog(@"arr == %@",arr1);
    NSInteger length = arr1.count;
    // 三個數(shù) 只需循環(huán)length - 2次;
    for (NSInteger i = 0; i < length - 2; i ++) {
        NSInteger left = i + 1;
        NSInteger right = length - 1;
        NSInteger m, n, l, all;
        while (left < right) {
            m = [arr1[i] integerValue];
            n = [arr1[left] integerValue];
            l = [arr1[right] integerValue];
            all = m + n + l;
            if (all == sum) {
                NSLog(@"have the sum");
                return YES;
            }
            if (all < sum) {
                left ++;
            }
            if (all > sum) {
                right --;
            }
        }
    }
    NSLog(@"have not the sum");
    return NO;
}

綜上第三種方法才是最優(yōu)解。
大家可以輸入測試代碼試一下,結(jié)果我就不演示了,應該沒有錯的,測試代碼給你們。

    [self seekRandomThreeElementSum1:5 Arr1:@[@(1),@(2),@(4),@(5),@(6),@(7),@(3)]];//沒有
    [self seekRandomThreeElementSum1:6 Arr1:@[@(1),@(2),@(3),@(4),@(5),@(6),@(7)]];//有
    [self seekRandomThreeElementSum1:7 Arr1:@[@(1),@(4),@(3),@(5),@(6),@(7)]];//沒有
    [self seekRandomThreeElementSum1:8 Arr1:@[@(1),@(4),@(3),@(5),@(6),@(7)]];//有
    [self seekRandomThreeElementSum1:3 Arr1:@[@(1),@(4),@(3),@(5),@(6),@(7)]];//沒有
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容