背景給定一個包含正數和負數的數組。您要在數組中找到一個等于某個值 X 的子數組。輸入是數組和 X 值。輸出是子數組的開始和結束索引。例子Array = [2,6,0,9,7,3,1,4,1,10] X = 15Output = [1,3]以下是我在geeks4geeks上找到的代碼 public static void subArraySum(int[] arr, int n, int sum) { //cur_sum to keep track of cummulative sum till that point int cur_sum = 0; int start = 0; int end = -1; HashMap<Integer, Integer> hashMap = new HashMap<>(); for (int i = 0; i < n; i++) { cur_sum = cur_sum + arr[i]; //check whether cur_sum - sum = 0, if 0 it means //the sub array is starting from index 0- so stop if (cur_sum - sum == 0) { start = 0; end = i; break; } //if hashMap already has the value, means we already // have subarray with the sum - so stop if (hashMap.containsKey(cur_sum - sum)) { start = hashMap.get(cur_sum - sum) + 1; end = i; break; } //if value is not present then add to hashmap hashMap.put(cur_sum, i); } // if end is -1 : means we have reached end without the sum if (end == -1) { System.out.println("No subarray with given sum exists"); } else { System.out.println("Sum found between indexes " + start + " to " + end); 問題 總的來說,我能夠理解為什么這個解決方案有效。具有條件的第一個塊cur_sum - sum == 0對我來說完全有意義。但是,我對hashMap.containsKey(cur_sum - sum)支票有效的原因感到非常困惑。我知道它每次都有效,但我想了解它背后的數學意義。我在一篇采訪博客中讀到,這使用了常見的差異技術,但我不確定這如何適用于此。在準備面試時,我并不是要記住這個解決方案,而是要對它的工作原理有一個深刻的理解。我花了幾個小時想出例子并手工追蹤它們,解決方案有效,但我無法理解為什么這種技術有效,我拒絕盲目地記住它。例如,如果我們談論的是一個只有正數的數組,那么我知道可以使用“滑動窗口”技術并且我能夠完全理解。當您擴展窗口時,總和會變大,而當您關閉窗口時,總和會變小。上述問題并非如此,因此希望得到一些幫助。
1 回答

SMILET
TA貢獻1796條經驗 獲得超4個贊
sum
- 是我們想要達到的數字
cur_sum
- 是到目前為止數組中所有元素的總和
比如說cur_sum - sum = x
我們在開始時更新的每個步驟cur_sum
,如果讓您感到困惑的條件評估為false
我們更新哈希圖并繼續。
到目前為止,一切都很好。
現在,為什么我們要查看是否x
已經在哈希圖中?
答案是,如果有一個先前的索引i
,其中直到該索引(包括)的所有元素的總和為x
,這意味著從索引i+1
到當前索引,我們有一個子數組,其總和為:cur_sum - x
并且因為我們已經知道這cur_sum - sum = x
意味著從i+1
當前索引開始和結束的子數組總和恰好為sum
.
讓我們以您發布的示例為例:
Array = [2,6,0,9,7,3,1,4,1,10] X = 15 Output = [1,3]
讓我們迭代數組:
索引 0:sum 2 => 使用 (0:2)
索引 1 更新地圖:sum 2+6=8 => 使用 (1:8)
索引 2 更新地圖:sum 2+6+0 =8 => 用 (2:8)
索引 3 更新地圖:總和 2+6+0+9=17 =>
但是現在我們可以看到映射已經包含 17-15=2 (0:2) 因此我們知道從索引 1 開始的子數組的總和(索引 1 在 (0:2) 的零之后)并結束于當前索引:3 - 這個子數組總和為 15。
添加回答
舉報
0/150
提交
取消