簡體   English   中英

我該如何解決這個問題,如果有的話,什么樣的算法適合解決它

[英]How can I solve this problem, and what kind of algorithm is the appropriate on if any to solve it

有一個包含非負整數的數組。 我需要找到一個包含總和等於給定數字(目標)的數字的子數組(如果有的話)。 我編寫了這個有效的代碼,但我嘗試以更有效的方式編寫它(O(n))。

public static void solvedNotSoEnhanced(int[] arr, int target) {
    for (int i = 0; i <= arr.length-1;i++) {
        int cur_sum = 0;
        for (int j = i ; j <= arr.length-1; j++) {
            cur_sum += arr[j];
            if (cur_sum > target) {
                break;
            } else if (cur_sum == target) {
                System.out.println("start: " + i + " end: " + j);
            }
        }
    }
}

訣竅在於限制:

有一個包含非負整數的數組。

這意味着當您從前到后遍歷輸入時,您假定子數組的“開始”位於索引 0,然后您開始按順序添加每個數字。 由於該限制,只有 3 個選項:

  1. 添加新數字會導致總和小於所需數字。 在這種情況下,繼續前進。
  2. 添加新號碼會導致與所需號碼完全匹配。 您已經找到了子序列並且算法完成了。
  3. 添加新數字會導致總和更多。 在這種情況下,唯一的答案可能在於移動啟動:元素 0不是解決方案的一部分。

因此:

static void solvedNotSoEnhanced(int[] arr, int target) {
    if (target < 1) {
        // Always mind your corner cases!
        System.out.println("(0, 0)");
        return;
    }

    int start = 0;
    int sum = 0;
    for (int i = 0; i < arr.length; i++) {
        sum += arr[i];

        while (sum > target) {
            // Target exceeded; move up our startpoint.
            sum -= arr[start];
            start++;
        }

        // If we get here, we found our subsequence!
        if (sum == target) {
            System.out.println("[" + start + ", " + i + "]");
            return;
        }
    }
    return "No subsequence";
}

這里我使用了滑動 window 的方法。 主要是我在遍歷數組時存儲數組元素的總和。 然后我只存儲 2 個指針 i 和 j,它們存儲正在考慮的當前子數組的 position。

public static void solvedNotSoEnhanced(int[] arr, int target) 
{
  for(int i = 1;i>arr.length;i++)
  {
    arr[i] += arr[i-1];
  }
  
  int i=0,j=1;
  while(i<arr.length &&j<arr.Length)
  {
    int sum = arr[j] - arr[i];
    if(sum == target) System.out.println("start: " + (i + 1) + " end: " + j);
    else if(sum > target) i++;
    else j++;
  }
}

它可以在O(nlogn + m)中完成,其中n是數組大小, m是匹配限制的子數組的數量。

首先,創建一個輔助數組sum ,它是當前所有元素的總和:

sum[i] = arr[0] + arr[1] + ... + arr[i]
Or (equivalent definition)
sum[0] = arr[0]
sum[i] = sum[i-1] + arr[i]

現在,請注意sum是排序(遞增)數組(因為所有元素都不是負數)。

因此,在生成數組之后,您可以迭代sum ,並且對於sum中的每個i ,使用二進制搜索查找k-sum[i] ,如果元素存在,它將為您提供索引j ,並且 (i,j) 是這樣的子數組。

也可以改為使用 hash 表來存儲總和,以進一步將復雜度降低到平均情況下的O(n)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM