📌  相关文章
📜  清空给定数组所需的给定类型的最小操作

📅  最后修改于: 2021-04-23 21:15:10             🧑  作者: Mango

给定大小为N的数组arr [] ,任务是找到删除所有数组元素所需的操作总数,以便如果数组的第一个元素是最小的元素,则删除该元素,否则移动第一个元素元素到数组的末尾。

例子:

天真的方法:解决问题的最简单方法是反复检查第一个数组元素是否为数组中的最小元素。如果发现为真,则删除该元素并增加计数。否则,将数组的第一个元素移到数组的末尾并增加计数。最后,打印获得的总数。
时间复杂度: O(N 3 )
辅助空间: O(N)

高效的方法:使用动态编程方法和排序算法可以有效地解决问题。请按照以下步骤解决问题:

  1. 将数组A []的元素及其索引存储到向量中 对,说向量a
  2. 根据元素的值对向量进行排序。
  3. 初始化数组countGreater_right []countGreater_left []分别存储给定数组中当前元素右侧存在的较大元素数和当前元素左侧存在的较大元素数,这可以使用set来完成数据结构。
  4. 最初,将向量a的起始元素的索引存储为prev = a [0] .second。
  5. prev + 1初始化计数
  6. 现在,遍历向量a的每个元素,从i = 1到N-1
  7. 对于每个元素,检索其原始索引为ind = a [i] .second ,每个元素的dp转换为:

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树在每个索引的左侧和右侧查找较大元素的数量来优化上述方法。