求所有奇数长度子数组的中位数之和
给定一个大小为N的数组arr[] ,任务是找到所有奇数长度子数组的中位数之和。
例子:
Input: arr[] = {4, 2, 5, 1}
Output: 18
Explanation : Sub-Arrays of odd length and their medians are :
- [4] -> Median is 4
- [4, 2, 5] -> Median is 4
- [2] -> Median is 2
- [2, 5, 1] -> Median is 2
- [5] -> Median is 5
- [1] -> Median is 1
Their sum = 4 + 4+ 2 + 2 + 5 +1 = 18
Input: arr[] = {1, 2}
Output: 3
先决条件:使用 STL 的运行整数流的中位数
天真的方法:生成每个子数组。如果子数组的长度为奇数,则对子数组进行排序并返回中间元素。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find sum of medians
// of all odd-length subarrays
int solve(vector arr)
{
int ans = 0;
int n = arr.size();
// Loop to calculate the sum
for(int i = 0; i < n; i++)
{
vector new_arr;
for(int j = i; j < n; j++)
{
new_arr.push_back(arr[j]);
// Odd length subarray
if ((new_arr.size() % 2) == 1)
{
sort(new_arr.begin(), new_arr.end());
int mid = new_arr.size() / 2;
ans += new_arr[mid];
}
}
}
return ans;
}
// Driver Code
int main()
{
vector arr = { 4, 2, 5, 1 };
cout << solve(arr);
}
// This code is contributed by Samim Hossain Mondal.
Java
// Java program for the above approach
import java.util.*;
class GFG {
// Function to find sum of medians
// of all odd-length subarrays
static int solve(int[] arr) {
int ans = 0;
int n = arr.length;
// Loop to calculate the sum
for (int i = 0; i < n; i++) {
List new_arr = new LinkedList();
for (int j = i; j < n; j++) {
new_arr.add(arr[j]);
// Odd length subarray
if ((new_arr.size() % 2) == 1) {
Collections.sort(new_arr);
int mid = new_arr.size() / 2;
ans += new_arr.get(mid);
}
}
}
return ans;
}
// Driver Code
public static void main(String[] args) {
int[] arr = { 4, 2, 5, 1 };
System.out.println(solve(arr));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python program for the above approach
# Function to find sum of medians
# of all odd-length subarrays
def solve(arr):
ans = 0
n = len(arr)
# Loop to calculate the sum
for i in range(n):
new_arr = []
for j in range(i, n, 1):
new_arr.append(arr[j])
# Odd length subarray
if (len(new_arr)) % 2 == 1:
new_arr.sort()
mid = len(new_arr)//2
ans += new_arr[mid]
return (ans)
# Driver Code
if __name__ == "__main__":
arr = [4, 2, 5, 1]
print(solve(arr))
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to find sum of medians
// of all odd-length subarrays
static int solve(int[] arr) {
int ans = 0;
int n = arr.Length;
// Loop to calculate the sum
for (int i = 0; i < n; i++) {
List new_arr = new List();
for (int j = i; j < n; j++) {
new_arr.Add(arr[j]);
// Odd length subarray
if ((new_arr.Count % 2) == 1) {
new_arr.Sort();
int mid = new_arr.Count / 2;
ans += new_arr[mid];
}
}
}
return ans;
}
// Driver Code
public static void Main() {
int[] arr = { 4, 2, 5, 1 };
Console.Write(solve(arr));
}
}
// This code is contributed by Saurabh Jaiswal
Javascript
Python3
# Python program for the above approach
from heapq import heappush as push, heappop as pop
# Find the sum of medians of odd-length
# subarrays
class find_median():
# Constructor to declare two heaps
def __init__(self):
# Store lower half elements such that
# maximum element is at top
self.max_heap = []
# Store higher half elements such that
# minimum element is at top
self.min_heap = []
def add(self, val):
# len(max_heap) == 0 or curr_element
# smaller than max_heap top
if (len(self.max_heap) == 0 or
self.max_heap[0] > val):
push(self.max_heap, -val)
else:
push(self.min_heap, val)
# If size of max_heap + 1 greater
# than min_heap
if (len(self.max_heap)+1 >
len(self.min_heap)):
val = pop(self.max_heap)
push(self.min_heap, -val)
# If size of min_heap
# greater than max_heap
if (len(self.min_heap) >
len(self.max_heap)):
val = pop(self.min_heap)
push(self.max_heap, -val)
# Finally if sum of sizes is odd,
# return median
if (len(self.min_heap) +
len(self.max_heap)) % 2 == 1:
return (-self.max_heap[0])
# Else return 0
else:
return 0
# Function to calculate the sum
# of all odd length subarrays
def solve(arr):
ans = 0
# Size of the array
n = len(arr)
for i in range(n):
# Create an object
# of class find_median
obj = find_median()
for j in range(i, n, 1):
# Add value to the heaps
# using object
val = obj.add(arr[j])
ans += val
return (ans)
# Driver Code
if __name__ == "__main__":
arr = [4, 2, 5, 1]
print(solve(arr))
输出
18
时间复杂度: O(N 3 * Log(N))
辅助空间: O(N)
注意:可以应用插入排序,而不是每次都对数组进行排序,这需要花费 ( N*logN) 。但是,总体时间复杂度仍然是O(N 3 )。
有效方法:排序数组的中位数是将数组中高半部分与低半部分分开的值。为了找出中位数,我们只需要中间元素,而不是整个排序数组。运行整数流中位数的方法可以在这里应用。按照下面提到的步骤
- 使用最大和最小堆计算运行中位数。
- 遍历数组中的每一个元素。
- 在创建新子数组时,将一个元素添加到堆中,如果大小为奇数则返回中值,否则返回 0。
- max_heap用于存储下半部分元素,使得最大元素在顶部, min_heap用于存储上半部分元素,使得最小元素在顶部。
- 两个堆之间的差异不应大于 1,并且一个额外的元素始终放置在max_heap中。
注意:这里的 max_heap 是使用 min_heap 实现的,只需将值取反,以便可以弹出最大的负元素。
下面是上述方法的实现:
Python3
# Python program for the above approach
from heapq import heappush as push, heappop as pop
# Find the sum of medians of odd-length
# subarrays
class find_median():
# Constructor to declare two heaps
def __init__(self):
# Store lower half elements such that
# maximum element is at top
self.max_heap = []
# Store higher half elements such that
# minimum element is at top
self.min_heap = []
def add(self, val):
# len(max_heap) == 0 or curr_element
# smaller than max_heap top
if (len(self.max_heap) == 0 or
self.max_heap[0] > val):
push(self.max_heap, -val)
else:
push(self.min_heap, val)
# If size of max_heap + 1 greater
# than min_heap
if (len(self.max_heap)+1 >
len(self.min_heap)):
val = pop(self.max_heap)
push(self.min_heap, -val)
# If size of min_heap
# greater than max_heap
if (len(self.min_heap) >
len(self.max_heap)):
val = pop(self.min_heap)
push(self.max_heap, -val)
# Finally if sum of sizes is odd,
# return median
if (len(self.min_heap) +
len(self.max_heap)) % 2 == 1:
return (-self.max_heap[0])
# Else return 0
else:
return 0
# Function to calculate the sum
# of all odd length subarrays
def solve(arr):
ans = 0
# Size of the array
n = len(arr)
for i in range(n):
# Create an object
# of class find_median
obj = find_median()
for j in range(i, n, 1):
# Add value to the heaps
# using object
val = obj.add(arr[j])
ans += val
return (ans)
# Driver Code
if __name__ == "__main__":
arr = [4, 2, 5, 1]
print(solve(arr))
输出
18
时间复杂度: O(N 2 * Log(N))
辅助空间: O(N)