📌  相关文章
📜  最长子数组,其元素可以通过最大K增量来相等

📅  最后修改于: 2021-05-14 07:26:12             🧑  作者: Mango

给定大小为N的正整数和正整数K的数组arr [] ,任务是找到子数组的最大可能长度,可以通过在子数组的每个元素上添加一些整数值来使子数组的长度相等,以使相加元素的总和不超过K。

例子:

方法:可以使用动态编程解决此问题。

  • 初始化:
    • dp [] :存储添加到子数组中的元素的总和。
    • deque :存储每个子数组的最大元素的索引。
    • pos:子数组当前位置的索引。
    • ans:最大子数组的长度。
    • mx:子数组的最大元素
    • pre:当前子数组的上一个索引。
  • 遍历数组,并检查双端队列是否为空。如果是,则更新最大元素和最大元素的索引以及prepos的索引。
  • 检查当前添加的元素是否大于K。如果是,则将其从dp []数组中删除并更新pospre的索引。
  • 最后更新有效子数组的最大长度。

下面是上述方法的实现:

C++
// C++ code for the above approach
 
#include 
using namespace std;
 
// Function to find maximum
// possible length of subarray
int validSubArrLength(int arr[],
                      int N, int K)
{
    // Stores the sum of elements
    // that needs to be added to
    // the sub array
    int dp[N + 1];
 
    // Stores the index of the
    // current position of subarray
    int pos = 0;
 
    // Stores the maximum
    // length of subarray.
    int ans = 0;
 
    // Maximum element from
    // each subarray length
    int mx = 0;
 
    // Previous index of the
    // current subarray of
    // maximum length
    int pre = 0;
 
    // Deque to store the indices
    // of maximum element of
    // each sub array
    deque q;
 
    // For each array element,
    // find the maximum length of
    // required subarray
    for (int i = 0; i < N; i++) {
        // Traverse the deque and
        // update the index of
        // maximum element.
        while (!q.empty()
               && arr[q.back()] < arr[i])
 
            q.pop_back();
 
        q.push_back(i);
 
        // If it is first element
        // then update maximum
        // and dp[]
        if (i == 0) {
            mx = arr[i];
            dp[i] = arr[i];
        }
 
        // Else check if current
        // element exceeds max
        else if (mx <= arr[i]) {
            // Update max and dp[]
            dp[i] = dp[i - 1] + arr[i];
            mx = arr[i];
        }
 
        else {
            dp[i] = dp[i - 1] + arr[i];
        }
 
        // Update the index of the
        // current maximum length
        // subarray
        if (pre == 0)
            pos = 0;
        else
            pos = pre - 1;
 
        // While current element
        // being added to dp[] array
        // exceeds K
        while ((i - pre + 1) * mx
                       - (dp[i] - dp[pos])
                   > K
               && pre < i) {
 
            // Update index of
            // current position and
            // the previous position
            pos = pre;
            pre++;
 
            // Remove elements
            // from deque and
            // update the
            // maximum element
            while (!q.empty()
                   && q.front() < pre
                   && pre < i) {
 
                q.pop_front();
                mx = arr[q.front()];
            }
        }
 
        // Update the maximum length
        // of the required subarray.
        ans = max(ans, i - pre + 1);
    }
    return ans;
}
 
// Driver Program
int main()
{
    int N = 6;
    int K = 8;
    int arr[] = { 2, 7, 1, 3, 4, 5 };
    cout << validSubArrLength(arr, N, K);
    return 0;
}


Java
// Java code for the above approach
import java.util.*;
 
class GFG{
 
// Function to find maximum
// possible length of subarray
static int validSubArrLength(int arr[],
                             int N, int K)
{
    // Stores the sum of elements
    // that needs to be added to
    // the sub array
    int []dp = new int[N + 1];
 
    // Stores the index of the
    // current position of subarray
    int pos = 0;
 
    // Stores the maximum
    // length of subarray.
    int ans = 0;
 
    // Maximum element from
    // each subarray length
    int mx = 0;
 
    // Previous index of the
    // current subarray of
    // maximum length
    int pre = 0;
 
    // Deque to store the indices
    // of maximum element of
    // each sub array
    Deque q = new LinkedList<>();
 
    // For each array element,
    // find the maximum length of
    // required subarray
    for(int i = 0; i < N; i++)
    {
         
       // Traverse the deque and
       // update the index of
       // maximum element.
       while (!q.isEmpty() &&
               arr[q.getLast()] < arr[i])
           q.removeLast();
       q.add(i);
        
       // If it is first element
       // then update maximum
       // and dp[]
       if (i == 0)
       {
           mx = arr[i];
           dp[i] = arr[i];
       }
        
       // Else check if current
       // element exceeds max
       else if (mx <= arr[i])
       {
            
           // Update max and dp[]
           dp[i] = dp[i - 1] + arr[i];
           mx = arr[i];
       }
       else
       {
           dp[i] = dp[i - 1] + arr[i];
       }
        
       // Update the index of the
       // current maximum length
       // subarray
       if (pre == 0)
           pos = 0;
       else
           pos = pre - 1;
        
       // While current element
       // being added to dp[] array
       // exceeds K
       while ((i - pre + 1) * mx -
          (dp[i] - dp[pos]) > K && pre < i)
       {
            
           // Update index of
           // current position and
           // the previous position
           pos = pre;
           pre++;
            
           // Remove elements from
           // deque and update the
           // maximum element
           while (!q.isEmpty() &&
                   q.peek() < pre && pre < i)
           {
               q.removeFirst();
               mx = arr[q.peek()];
           }
       }
        
       // Update the maximum length
       // of the required subarray.
       ans = Math.max(ans, i - pre + 1);
    }
    return ans;
}
 
// Driver code
public static void main(String[] args)
{
    int N = 6;
    int K = 8;
    int arr[] = { 2, 7, 1, 3, 4, 5 };
     
    System.out.print(validSubArrLength(arr, N, K));
}
}
 
// This code is contributed by amal kumar choubey


Python3
# Python3 code for the above approach
 
# Function to find maximum
# possible length of subarray
def validSubArrLength(arr, N, K):
     
    # Stores the sum of elements
    # that needs to be added to
    # the sub array
    dp = [0 for i in range(N + 1)]
 
    # Stores the index of the
    # current position of subarray
    pos = 0
 
    # Stores the maximum
    # length of subarray.
    ans = 0
 
    # Maximum element from
    # each subarray length
    mx = 0
 
    # Previous index of the
    # current subarray of
    # maximum length
    pre = 0
 
    # Deque to store the indices
    # of maximum element of
    # each sub array
    q = []
 
    # For each array element,
    # find the maximum length of
    # required subarray
    for i in range(N):
         
        # Traverse the deque and
        # update the index of
        # maximum element.
        while (len(q) and arr[len(q) - 1] < arr[i]):
            q.remove(q[len(q) - 1])
 
        q.append(i)
 
        # If it is first element
        # then update maximum
        # and dp[]
        if (i == 0):
            mx = arr[i]
            dp[i] = arr[i]
 
        # Else check if current
        # element exceeds max
        elif (mx <= arr[i]):
             
            # Update max and dp[]
            dp[i] = dp[i - 1] + arr[i]
            mx = arr[i]
 
        else:
            dp[i] = dp[i - 1] + arr[i]
 
        # Update the index of the
        # current maximum length
        # subarray
        if (pre == 0):
            pos = 0
        else:
            pos = pre - 1
 
        # While current element
        # being added to dp[] array
        # exceeds K
        while ((i - pre + 1) *
               mx - (dp[i] - dp[pos]) > K and
              pre < i):
                   
            # Update index of
            # current position and
            # the previous position
            pos = pre
            pre += 1
 
            # Remove elements
            # from deque and
            # update the
            # maximum element
            while (len(q) and
                   q[0] < pre and
                   pre < i):
                q.remove(q[0])
                mx = arr[q[0]]
 
        # Update the maximum length
        # of the required subarray.
        ans = max(ans, i - pre + 1)
         
    return ans
 
# Driver code
if __name__ == '__main__':
     
    N = 6
    K = 8
     
    arr =  [ 2, 7, 1, 3, 4, 5 ]
     
    print(validSubArrLength(arr, N, K))
 
# This code is contributed by ipg2016107


输出:
4



时间复杂度: O(N 2 )
辅助空间复杂度: O(N)