📜  总和可被 k 整除的最长子数组

📅  最后修改于: 2021-10-27 07:17:23             🧑  作者: Mango

给定一个包含n 个整数和一个正整数karr[] 。问题是找到最长子数组的长度以及可被给定值k整除的元素的总和。
例子:

Input : arr[] = {2, 7, 6, 1, 4, 5}, k = 3
Output : 4
The subarray is {7, 6, 1, 4} with sum 18,
which is divisible by 3.

Input : arr[] = {-2, 2, -5, 12, -11, -1, 7}
Output : 5

方法一(Naive Approach):考虑所有子数组,返回总和能被k整除且长度最长的子数组的长度。
时间复杂度:O(n 2 )。
方法 2(高效方法):创建一个数组mod_arr[] ,其中mod_arr[i]存储(sum(arr[0]+arr[1]..+arr[i]) % k) 。创建一个具有散列表元组为(ELE,IDX),其中ELE表示mod_arr []的元素与IDX表示mod_arr第一次出现的元素的索引[]。现在,从 i = 0 到 n 遍历mod_arr[]并按照下面给出的步骤进行操作。

  1. 如果 mod_arr[i] == 0,则更新maxLen = (i + 1)。
  2. 否则,如果哈希表中不存在 mod_arr[i],则在哈希表中创建元组(mod_arr[i], i)
  3. 否则,在哈希表中获取与mod_arr[i]关联的值。让它成为idx
  4. 如果 maxLen < (i – idx),则更新maxLen = (i – idx)。

最后返回maxLen

C++
// C++ implementation to find the longest subarray
// with sum divisible by k
#include 
 
using namespace std;
 
// function to find the longest subarray
// with sum divisible by k
int longSubarrWthSumDivByK(int arr[],
                          int n, int k)
{
    // unodered map 'um' implemented as
    // hash table
    unordered_map um;
     
    // 'mod_arr[i]' stores (sum[0..i] % k)
    int mod_arr[n], max = 0;
    int curr_sum = 0;
     
    // traverse arr[] and build up the
    // array 'mod_arr[]'
    for (int i = 0; i < n; i++)
    {
        curr_sum += arr[i];
         
        // as the sum can be negative, taking modulo twice
        mod_arr[i] = ((curr_sum % k) + k) % k;       
    }   
     
    for (int i = 0; i < n; i++)
    {
        // if true then sum(0..i) is divisible
        // by k
        if (mod_arr[i] == 0)
            // update 'max'
            max = i + 1;
         
        // if value 'mod_arr[i]' not present in 'um'
        // then store it in 'um' with index of its
        // first occurrence       
        else if (um.find(mod_arr[i]) == um.end())
            um[mod_arr[i]] = i;
             
        else
            // if true, then update 'max'
            if (max < (i - um[mod_arr[i]]))
                max = i - um[mod_arr[i]];           
    }
     
    // required length of longest subarray with
    // sum divisible by 'k'
    return max;
}                         
 
// Driver program to test above
int main()
{
    int arr[] = {2, 7, 6, 1, 4, 5};
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 3;
     
    cout << "Length = "
         << longSubarrWthSumDivByK(arr, n, k);
          
    return 0;    
}


Java
// Java implementation to find the longest
// subarray with sum divisible by k
import java.io.*;
import java.util.*;
 
class GfG {
         
    // function to find the longest subarray
    // with sum divisible by k
    static int longSubarrWthSumDivByK(int arr[],
                                      int n, int k)
    {
        // unodered map 'um' implemented as
        // hash table
        HashMap um= new HashMap();
         
        // 'mod_arr[i]' stores (sum[0..i] % k)
        int mod_arr[]= new int[n];
        int max = 0;
        int curr_sum = 0;
         
        // traverse arr[] and build up the
        // array 'mod_arr[]'
        for (int i = 0; i < n; i++)
        {
            curr_sum += arr[i];
             
            // as the sum can be negative,
            // taking modulo twice
            mod_arr[i] = ((curr_sum % k) + k) % k;    
        }
         
        for (int i = 0; i < n; i++)
        {
            // if true then sum(0..i) is
            // divisible by k
            if (mod_arr[i] == 0)
                // update 'max'
                max = i + 1;
             
            // if value 'mod_arr[i]' not present in 'um'
            // then store it in 'um' with index of its
            // first occurrence    
            else if (um.containsKey(mod_arr[i]) == false)
                um.put(mod_arr[i] , i);
                 
            else
                // if true, then update 'max'
                if (max < (i - um.get(mod_arr[i])))
                    max = i - um.get(mod_arr[i]);        
        }
         
        // required length of longest subarray with
        // sum divisible by 'k'
        return max;
    }   
     
    public static void main (String[] args)
    {
        int arr[] = {2, 7, 6, 1, 4, 5};
        int n = arr.length;
        int k = 3;
         
        System.out.println("Length = "+
                            longSubarrWthSumDivByK(arr, n, k));
         
    }
}
 
// This code is contributed by Gitanjali.


Python3
# Python3 implementation to find the
# longest subarray with sum divisible by k
 
# Function to find the longest
# subarray with sum divisible by k
def longSubarrWthSumDivByK(arr, n, k):
     
    # unodered map 'um' implemented
    # as hash table
    um = {}
 
    # 'mod_arr[i]' stores (sum[0..i] % k)
    mod_arr = [0 for i in range(n)]
    max = 0
    curr_sum = 0
     
    # Traverse arr[] and build up
    # the array 'mod_arr[]'
    for i in range(n):
        curr_sum += arr[i]
         
        # As the sum can be negative,
        # taking modulo twice
        mod_arr[i] = ((curr_sum % k) + k) % k
     
    for i in range(n):
         
        # If true then sum(0..i) is
        # divisible by k
        if (mod_arr[i] == 0):
             
            # Update 'max'
            max = i + 1
         
        # If value 'mod_arr[i]' not present in
        # 'um' then store it in 'um' with index
        # of its first occurrence
        elif (mod_arr[i] not in um):
            um[mod_arr[i]] = i
             
        else:
             
            # If true, then update 'max'
            if (max < (i - um[mod_arr[i]])):
                max = i - um[mod_arr[i]]        
     
    # Required length of longest subarray
    # with sum divisible by 'k'
    return max   
 
# Driver Code
if __name__ == '__main__':
     
    arr = [ 2, 7, 6, 1, 4, 5 ]
    n = len(arr)
    k = 3
     
    print("Length =",
           longSubarrWthSumDivByK(arr, n, k))
     
# This code is contributed by
# Surendra_Gangwar


C#
using System;
using System.Collections.Generic;
 
// C# implementation to find the longest 
// subarray with sum divisible by k
 
public class GfG
{
 
    // function to find the longest subarray
    // with sum divisible by k
    public static int longSubarrWthSumDivByK(int[] arr, int n, int k)
    {
        // unodered map 'um' implemented as
        // hash table
        Dictionary um = new Dictionary();
 
        // 'mod_arr[i]' stores (sum[0..i] % k)
        int[] mod_arr = new int[n];
        int max = 0;
        int curr_sum = 0;
 
        // traverse arr[] and build up the
        // array 'mod_arr[]'
        for (int i = 0; i < n; i++)
        {
            curr_sum += arr[i];
 
            // as the sum can be negative, 
            // taking modulo twice
            mod_arr[i] = ((curr_sum % k) + k) % k;
        }
 
        for (int i = 0; i < n; i++)
        {
            // if true then sum(0..i) is 
            // divisible by k
            if (mod_arr[i] == 0)
            {
                // update 'max'
                max = i + 1;
            }
 
            // if value 'mod_arr[i]' not present in 'um'
            // then store it in 'um' with index of its
            // first occurrence     
            else if (um.ContainsKey(mod_arr[i]) == false)
            {
                um[mod_arr[i]] = i;
            }
 
            else
            {
                // if true, then update 'max'
                if (max < (i - um[mod_arr[i]]))
                {
                    max = i - um[mod_arr[i]];
                }
            }
        }
 
        // required length of longest subarray with
        // sum divisible by 'k'
        return max;
    }
 
    public static void Main(string[] args)
    {
        int[] arr = new int[] {2, 7, 6, 1, 4, 5};
        int n = arr.Length;
        int k = 3;
 
        Console.WriteLine("Length = " + longSubarrWthSumDivByK(arr, n, k));
 
    }
}
 
// This code is contributed by Shrikant13


Javascript


输出:

Length = 4 

时间复杂度:O(n)。
辅助空间:O(n^2)。
这种方法的时间复杂度可以通过使用大小等于 k 的数组进行 O(1) 查找来改进,因为在对输入数组的元素使用模运算后,所有元素都将小于 k。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程