2015-10-06 43 views
4

受歡迎的訪談問題:是否有一個子目標與目標相加?

給定一個正整數和一個目標整數的數組,找出是否有一個連續的子數組與目標相加。

E.g.

陣列= [1,3,6,7,8,10] 目標= 16 求和至16是[3,6,7],所以它返回真子陣列。

+0

請檢查下面給出的答案,謝謝。 –

+0

等一下......你想用什麼語言? –

+0

任何語言都可以。這更多的是關於邏輯。 @TimBiegeleisen,你的回答是有道理的,它似乎工作。就複雜性而言,這似乎是O(N^2)。有什麼辦法可以提高效率嗎? –

回答

6

這是線性時間(C++代碼)。

bool Test(const int* arr, int size, int target) { 
    if (target < 0) return false; 
    int acc = 0; 
    int i = 0, j = 0; 
    while (acc != target) { 
    if (acc < target) { 
     if (j == size) break; 
     acc += arr[j++]; 
    } 
    else { 
     acc -= arr[i++]; 
    } 
    } 
    return acc == target; 
} 

注意,預檢查爲陰性目標值是必要的,以保證循環不變的是i <= j。具體而言,當i == j,acc將是0,並且正目標保證if (acc < target)下的分支被命中。

+1

@TonyD我不這麼認爲。如問題中所述,它假定數組中存在正整數。 – Lingxi

+0

它看起來像處理目標= 0錯誤....你說「積極的目標」,但檢查非負..... –

+0

@ gen-ys當「target」爲「0」時,「while」循環根本不被輸入,並返回'acc == target'(這是'true')。所以,目標值「0」總是導致返回「true」。當我們把一個空的子數組的總和看作'0'時,這應該是正確的。 – Lingxi

1

剛剛寫完並經過充分測試。 hasConsec(其中大部分邏輯是)和sumArr(在數組中求和值的幫助器方法)兩種方法。 hasConsec並使用2個索引(第一個和最後一個)創建子陣列。輔助方法用於對創建的子數組進行求和,然後hasConsec檢查它是否與目標匹配,是否大於目標,或者是否小於目標。如果匹配,則返回true;如果總和小於目標,則最後一個索引增加;如果它大於目標,則第一個索引增加。重複,直到第一個索引等於數組的長度。如果發生這種情況,則不會有子目標與目標相加。返回false;

public static boolean hasConsec(int arr[], int target) { 
    int first = 0, last = 0; 

    while (last < arr.length) { 
     int sub[] = Arrays.copyOfRange(arr, first, last); 
     int subSum = sumArr(sub); 
     if (subSum == target) 
      return true; 
     else if (subSum < target) 
      last++; 
     else { 
      if (++first < last) 
       last = first; 
     } 
    } 
    return false; 
} 

public static int sumArr(int arr[]) { 
    int sum = 0; 
    for (int i = 0; i < arr.length; i++) 
     sum += arr[i]; 
    return sum; 
} 
相關問題