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

📅  最后修改于: 2021-09-06 05:38:10             🧑  作者: Mango

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

例子:

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

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

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

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