给定大小为N的数组arr [] ,任务是找到删除所有数组元素所需的操作总数,以便如果数组的第一个元素是最小的元素,则删除该元素,否则移动第一个元素元素到数组的末尾。
例子:
Input: A[] = {8, 5, 2, 3}
Output: 7
Explanation: Initially, A[] = {8, 5, 2, 3}
Step 1: 8 is not the smallest. Therefore, moving it to the end of the array modifes A[] to {5, 2, 3, 8}.
Step 2: 5 is not the smallest. Therefore, moving it to the end of the array modifes A[] to {2, 3, 8, 5}.
Step 3: 2 is the smallest. Therefore, removing it from the array modifes A[] to {3, 8, 5}
Step 4: 3 is the smallest. Therefore, removing it from the array modifes A[] to A[] = {5, 8}
Step 6: 5 is smallest. Therefore, removing it from the array modifes A[] to {8}
Step 7: 8 is the smallest. Therefore, removing it from the array modifes A[] to {}
Therefore, 7 operations are required to delete the whole array.
Input: A[] = {8, 6, 5, 2, 7, 3, 10}
Output: 18
天真的方法:解决问题的最简单方法是反复检查第一个数组元素是否为数组中的最小元素。如果发现为真,则删除该元素并增加计数。否则,将数组的第一个元素移到数组的末尾并增加计数。最后,打印获得的总数。
时间复杂度: O(N 3 )
辅助空间: O(N)
高效的方法:使用动态编程方法和排序算法可以有效地解决问题。请按照以下步骤解决问题:
- 将数组A []的元素及其索引存储到向量中 对,说向量a 。
- 根据元素的值对向量进行排序。
- 初始化数组countGreater_right []和countGreater_left []分别存储给定数组中当前元素右侧存在的较大元素数和当前元素左侧存在的较大元素数,这可以使用set来完成数据结构。
- 最初,将向量a的起始元素的索引存储为prev = a [0] .second。
- 用prev + 1初始化计数。
- 现在,遍历向量a的每个元素,从i = 1到N-1 。
- 对于每个元素,检索其原始索引为ind = a [i] .second ,每个元素的dp转换为:
If ind > prev, increment count by countGreater_right[prev] – countGreater_right[ind], otherwise
Increment count by countGreater_right[prev] + countGreater_left[ind] + 1.
8.遍历后,打印计数作为答案。
下面是上述算法的实现:
C++
// C++ program for the above approach
#include
#include
using namespace std;
// Function to find the count of greater
// elements to right of each index
void countGreaterRight(int A[], int len,
int* countGreater_right)
{
// Store elements of array
// in sorted order
multiset s;
// Traverse the array in reverse order
for (int i = len - 1; i >= 0; i--) {
auto it = s.lower_bound(A[i]);
// Stores count of greater elements
// on the right of i
countGreater_right[i]
= distance(it, s.end());
// Insert current element
s.insert(A[i]);
}
}
// Function to find the count of greater
// elements to left of each index
void countGreaterLeft(int A[], int len,
int* countGreater_left)
{
// Stores elements in
// a sorted order
multiset s;
// Traverse the array
for (int i = 0; i <= len; i++) {
auto it = s.lower_bound(A[i]);
// Stores count of greater elements
// on the left side of i
countGreater_left[i]
= distance(it, s.end());
// Insert current element into multiset
s.insert(A[i]);
}
}
// Function to find the count of operations required
// to remove all the array elements such that If
// 1st elements is smallest then remove the element
// otherwise move the element to the end of array
void cntOfOperations(int N, int A[])
{
int i;
// Store {A[i], i}
vector a;
// Traverse the array
for (i = 0; i < N; i++) {
// Insert {A[i], i}
a.push_back(make_pair(A[i], i));
}
// Sort the vector pair according to
// elements of the array, A[]
sort(a.begin(), a.end());
// countGreater_right[i]: Stores count of
// greater elements on the right side of i
int countGreater_right[N];
// countGreater_left[i]: Stores count of
// greater elements on the left side of i
int countGreater_left[N];
// Function to fill the arrays
countGreaterRight(A, N, countGreater_right);
countGreaterLeft(A, N, countGreater_left);
// Index of smallest element
// in array A[]
int prev = a[0].second, ind;
// Stores count of greater element
// on left side of index i
int count = prev + 1;
// Iterate over remaining elements
// in of a[][]
for (i = 1; i prev) {
// Update count
count += countGreater_right[prev]
- countGreater_right[ind];
}
else {
// Update count
count += countGreater_right[prev]
+ countGreater_left[ind] + 1;
}
// Update prev
prev = ind;
}
// Print count as total number
// of operations
cout << count;
}
// Driver Code
int main()
{
// Given array
int A[] = { 8, 5, 2, 3 };
// Given size
int N = sizeof(A) / sizeof(A[0]);
// Function Call
cntOfOperations(N, A);
return 0;
}
Python3
# Python3 program for the above approach
from bisect import bisect_left, bisect_right
# Function to find the count of greater
# elements to right of each index
def countGreaterRight(A, lenn,countGreater_right):
# Store elements of array
# in sorted order
s = {}
# Traverse the array in reverse order
for i in range(lenn-1, -1, -1):
it = bisect_left(list(s.keys()), A[i])
# Stores count of greater elements
# on the right of i
countGreater_right[i] = it
# Insert current element
s[A[i]] = 1
return countGreater_right
# Function to find the count of greater
# elements to left of each index
def countGreaterLeft(A, lenn,countGreater_left):
# Store elements of array
# in sorted order
s = {}
# Traverse the array in reverse order
for i in range(lenn):
it = bisect_left(list(s.keys()), A[i])
# Stores count of greater elements
# on the right of i
countGreater_left[i] = it
# Insert current element
s[A[i]] = 1
return countGreater_left
# Function to find the count of operations required
# to remove all the array elements such that If
# 1st elements is smallest then remove the element
# otherwise move the element to the end of array
def cntOfOperations(N, A):
# Store {A[i], i}
a = []
# Traverse the array
for i in range(N):
# Insert {A[i], i}
a.append([A[i], i])
# Sort the vector pair according to
# elements of the array, A[]
a = sorted(a)
# countGreater_right[i]: Stores count of
# greater elements on the right side of i
countGreater_right = [0 for i in range(N)]
# countGreater_left[i]: Stores count of
# greater elements on the left side of i
countGreater_left = [0 for i in range(N)]
# Function to fill the arrays
countGreater_right = countGreaterRight(A, N,
countGreater_right)
countGreater_left = countGreaterLeft(A, N,
countGreater_left)
# Index of smallest element
# in array A[]
prev, ind = a[0][1], 0
# Stores count of greater element
# on left side of index i
count = prev
# Iterate over remaining elements
# in of a[][]
for i in range(N):
# Index of next smaller element
ind = a[i][1]
# If ind is greater
if (ind > prev):
# Update count
count += countGreater_right[prev] - countGreater_right[ind]
else:
# Update count
count += countGreater_right[prev] + countGreater_left[ind] + 1
# Update prev
prev = ind
# Prcount as total number
# of operations
print (count)
# Driver Code
if __name__ == '__main__':
# Given array
A = [8, 5, 2, 3 ]
# Given size
N = len(A)
# Function Call
cntOfOperations(N, A)
# This code is contributed by mohit kumar 29
7
时间复杂度: O(N 2 )
辅助空间: O(N)
注意:可以通过使用Fenwick树在每个索引的左侧和右侧查找较大元素的数量来优化上述方法。