从等于某个值X

时间:2019-05-26 02:34:42

标签: java sub-array

背景

将为您提供一个包含正数和负数的数组。 您将在数组中找到一个等于某个值X的子数组。 输入是数组和X值。 输出是子数组的开始和结束索引。

示例

Array = [2,6,0,9,7,3,1,4,1,10] 
X = 15
Output = [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)支票为什么起作用感到非常困惑。我知道它每次都有效,但是我想了解它背后的数学意义。我在一个采访博客中读到,它使用了通用的diff技术,但是我不确定这如何应用于此。

在准备面试时,我并不是要记住这种解决方案,而是要对它为什么起作用有一个坚实的了解。

我花了数小时来提出示例,并通过手工对其进行跟踪,并且解决方案有效,但是我无法理解该技术为何起作用,因此我拒绝盲目地记住它。

例如,如果我们只谈论带有正数的数组,那么我知道可以使用“滑动窗口”技术,并且我能够完全理解。扩展窗口时,总和变大;关闭窗口时,总和变小。上面的问题不是这种情况,因此将对您有所帮助。

1 个答案:

答案 0 :(得分:0)

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:总和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。