给定一个大小为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 modifies A[] to {5, 2, 3, 8}.
Step 2: 5 is not the smallest. Therefore, moving it to the end of the array modifies A[] to {2, 3, 8, 5}.
Step 3: 2 is the smallest. Therefore, removing it from the array modifies A[] to {3, 8, 5}
Step 4: 3 is the smallest. Therefore, removing it from the array modifies A[] to A[] = {5, 8}
Step 6: 5 is smallest. Therefore, removing it from the array modifies A[] to {8}
Step 7: 8 is the smallest. Therefore, removing it from the array modifies 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[]以分别存储给定数组中当前元素右侧存在的较大元素的数量和当前元素左侧存在的较大元素的数量,这可以使用集合来完成数据结构。
- 最初,将向量 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.遍历后打印count作为答案。
下面是上述算法的实现:
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 Tree 查找每个索引左侧和右侧的较大元素的数量来优化上述方法。
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live