📌  相关文章
📜  用于查找具有给定总和的子数组的Python程序 - 集合 1(非负数)

📅  最后修改于: 2022-05-13 01:56:56.363000             🧑  作者: Mango

用于查找具有给定总和的子数组的Python程序 - 集合 1(非负数)

给定一个未排序的非负整数数组,找到一个与给定数字相加的连续子数组。
例子 :

Input: arr[] = {1, 4, 20, 3, 10, 5}, sum = 33
Output: Sum found between indexes 2 and 4
Sum of elements between indices
2 and 4 is 20 + 3 + 10 = 33

Input: arr[] = {1, 4, 0, 0, 3, 10, 5}, sum = 7
Output: Sum found between indexes 1 and 4
Sum of elements between indices
1 and 4 is 4 + 0 + 0 + 3 = 7

Input: arr[] = {1, 4}, sum = 0
Output: No subarray found
There is no subarray with 0 sum

可能有多个子数组以 sum 作为给定的总和。以下解决方案首先打印这样的子数组。

简单方法:一个简单的解决方案是逐个考虑所有子数组并检查每个子数组的总和。以下程序实现了简单的解决方案。运行两个循环:外循环选择起点 I,内循环尝试从 i 开始的所有子数组。
算法:

  1. 从头到尾遍历数组。
  2. 从每个索引开始另一个从i到数组末尾的循环以获取从 i 开始的所有子数组,并保留一个变量 sum 来计算总和。
  3. 对于内部循环中的每个索引更新sum = sum + array[j]
  4. 如果总和等于给定的总和,则打印子数组。
Python3
# Python program to implement
# the above approach
# Returns true if the there is a subarray
# of arr[] with sum equal to 'sum' otherwise 
# returns false. Also, prints the result 
def subArraySum(arr, n, sum_):
      
    # Pick a starting point
    for i in range(n):
        curr_sum = arr[i]
      
        # Try all subarrays starting 
        # with 'i'
        j = i + 1
        while j <= n:        
            if curr_sum == sum_:
                print ("Sum found between")
                print("indexes % d and % d"%( i, j-1))                
                return 1
                  
            if curr_sum > sum_ or j == n:
                break
              
            curr_sum = curr_sum + arr[j]
            j += 1
  
    print ("No subarray found")
    return 0
  
# Driver code
arr = [15, 2, 4, 8, 9, 5, 10, 23]
n = len(arr)
sum_ = 23
  
subArraySum(arr, n, sum_)
# This code is contributed by shreyanshi_arun.


Python3
# An efficient program to print 
# subarray with sum as given sum 
  
# Returns true if the there is a subarray 
# of arr[] with sum equal to 'sum' otherwise 
# returns false. Also, prints the result.
def subArraySum(arr, n, sum_):
      
    # Initialize curr_sum as value of 
    # first element and starting point 
    # as 0 
    curr_sum = arr[0]
    start = 0
  
    # Add elements one by one to curr_sum 
    # and if the curr_sum exceeds the sum, 
    # then remove starting element 
    i = 1
    while i <= n:
          
        # If curr_sum exceeds the sum, 
        # then remove the starting elements
        while curr_sum > sum_ and start < i-1:
          
            curr_sum = curr_sum - arr[start]
            start += 1
              
        # If curr_sum becomes equal to sum, 
        # then return true
        if curr_sum == sum_:
            print ("Sum found between indexes")
            print ("% d and % d"%(start, i-1))
            return 1
  
        # Add this element to curr_sum
        if i < n:
            curr_sum = curr_sum + arr[i]
        i += 1
  
    # If we reach here, then no subarray
    print ("No subarray found")
    return 0
  
# Driver code
arr = [15, 2, 4, 8, 9, 5, 10, 23]
n = len(arr)
sum_ = 23
subArraySum(arr, n, sum_)
# This code is contributed by shreyanshi_arun.


输出 :

Sum found between indexes 1 and 4

复杂性分析:

  • 时间复杂度:最坏情况下为 O(n^2)。
    嵌套循环用于遍历数组,因此时间复杂度为 O(n^2)
  • 空间复杂度: O(1)。
    因为需要恒定的额外空间。

有效方法:如果数组的所有元素都是正数,则有一个想法。如果子数组的总和大于给定的总和,则将元素添加到当前子数组的总和不可能是x (给定总和)。想法是对滑动窗口使用类似的方法。从一个空子数组开始,向子数组添加元素,直到总和小于x 。如果总和大于x ,则从当前子数组的开头删除元素。
算法:

  1. 创建三个变量, l=0,sum=0
  2. 从头到尾遍历数组。
  3. 通过添加当前元素来更新变量 sum, sum = sum + array[i]
  4. 如果总和大于给定总和,则将变量 sum 更新为sum = sum – array[l] ,并将 l 更新为 l++。
  5. 如果总和等于给定总和,则打印子数组并中断循环。

Python3

# An efficient program to print 
# subarray with sum as given sum 
  
# Returns true if the there is a subarray 
# of arr[] with sum equal to 'sum' otherwise 
# returns false. Also, prints the result.
def subArraySum(arr, n, sum_):
      
    # Initialize curr_sum as value of 
    # first element and starting point 
    # as 0 
    curr_sum = arr[0]
    start = 0
  
    # Add elements one by one to curr_sum 
    # and if the curr_sum exceeds the sum, 
    # then remove starting element 
    i = 1
    while i <= n:
          
        # If curr_sum exceeds the sum, 
        # then remove the starting elements
        while curr_sum > sum_ and start < i-1:
          
            curr_sum = curr_sum - arr[start]
            start += 1
              
        # If curr_sum becomes equal to sum, 
        # then return true
        if curr_sum == sum_:
            print ("Sum found between indexes")
            print ("% d and % d"%(start, i-1))
            return 1
  
        # Add this element to curr_sum
        if i < n:
            curr_sum = curr_sum + arr[i]
        i += 1
  
    # If we reach here, then no subarray
    print ("No subarray found")
    return 0
  
# Driver code
arr = [15, 2, 4, 8, 9, 5, 10, 23]
n = len(arr)
sum_ = 23
subArraySum(arr, n, sum_)
# This code is contributed by shreyanshi_arun.

输出 :

Sum found between indexes 1 and 4

复杂性分析:

  • 时间复杂度: O(n)。
    只需要遍历一次数组。所以时间复杂度是O(n)。
  • 空间复杂度: O(1)。
    因为需要恒定的额外空间。

请参考完整的文章 Find subarray with given sum |设置 1(非负数)了解更多详情!