📌  相关文章
📜  为具有重复元素的数组获得严格的 LIS 所需的最小串联 |组 2

📅  最后修改于: 2021-10-26 06:40:56             🧑  作者: Mango

给定一个大小为 n 的数组 A[] ,其中数组中可以有重复的元素。我们必须找到序列 A 所需的最小串联才能严格获得最长递增子序列。对于数组 A[],我们遵循基于 1 的索引。

例子:

方法:
为了解决上面提到的问题,第一个观察结果是严格递增的子序列的长度总是等于序列 A[] 中存在的唯一元素的数量。因此,子序列的最大长度等于不同元素的数量。要解决问题,请按照以下步骤操作:

  • 初始化一个变量,假设ans为 1 并将序列分成两半,左子序列和右子序列。将 leftSeq 初始化为 NULL 并复制 rightSeq 中的原始序列。
  • 在右子序列中遍历找到最小的元素,用变量CurrElement表示,并存储其索引。
  • 现在更新左右子序列,其中 leftSeq 用给定的序列更新,直到索引存储右子序列中的最小元素。以及从最小索引值到结束的给定序列的 rightSeq。
  • 遍历数组以获取下一个最小元素并更新 CurrElement 的值。如果 rightSeq 中没有这样的最小值,那么它必须在 leftSeq 中。在左子序列中找到该元素的索引并存储其索引。
  • 现在再次更新左右子序列的值,其中 leftSeq = 到第 k 个索引的给定序列和 rightSeq = 从第 k 个索引到结尾的给定序列。重复该过程,直到达到阵列限制。
  • ans的值增加 1,并在 CurrElement 等于最高元素时停止。

下面是上述方法的实现:

C++
// C++ implementation to Find the minimum
// concatenation required to get strictly
// Longest Increasing Subsequence for the
// given array with repetitive elements
#include 
using namespace std;
 
int LIS(int arr[], int n)
{
    // ordered map containing value and
    // a vector containing index of
    // it's occurrences
    map > m;
 
    // Mapping index with their values
    // in ordered map
    for (int i = 0; i < n; i++)
        m[arr[i]].push_back(i);
 
    // k refers to present minimum index
    int k = n;
 
    // Stores the number of concatenation
    // required
    int ans = 0;
 
    // Iterate over map m
    for (auto it = m.begin(); it != m.end();
                                       it++) {
        // it.second refers to the vector
        // containing all corresponding
        // indexes
 
        // it.second.back refers to the
        // last element of corresponding vector
 
        if (it->second.back() < k) {
            k = it->second[0];
            ans += 1;
        }
        else
 
            // find the index of next minimum
            // element in the sequence
            k = *lower_bound(it->second.begin(),
                            it->second.end(), k);
    }
 
    // Return the final answer
    cout << ans << endl;
}
 
// Driver program
int main()
{
    int arr[] = { 1, 3, 2, 1, 2 };
 
    int n = sizeof(arr) / sizeof(arr[0]);
 
    LIS(arr, n);
 
    return 0;
}


Java
// Java implementation to Find the minimum
// concatenation required to get strictly
// Longest Increasing Subsequence for the
// given array with repetitive elements
import java.io.*;
import java.util.*;
 
class GFG{
 
static void LIS(int arr[], int n)
{
     
    // ordered map containing value and
    // a vector containing index of
    // it's occurrences
    TreeMap> m = new TreeMap>();
     
    // Mapping index with their values
    // in ordered map
    for(int i = 0; i < n; i++)
    {
        List indexes;
         
        if (m.containsKey(arr[i]))
        {
            indexes = m.get(arr[i]);
        }
        else
        {
            indexes = new ArrayList();
        }
        indexes.add(i);
        m.put(arr[i], indexes);
    }
     
    // k refers to present minimum index
    int k = n;
 
    // Stores the number of concatenation
    // required
    int ans = 0;
 
    // Iterate over map m
    for(Map.Entry> it : m.entrySet())
    {
         
        // List containing all corresponding
        // indexes
        List indexes = it.getValue();
 
        if (indexes.get(indexes.size() - 1) < k)
        {
            k = indexes.get(0);
            ans++;
        }
        else
         
            // Find the index of next minimum
            // element in the sequence
            k = lower_bound(indexes, k);
    }
     
    // Return the final answer
    System.out.println(ans);
}
 
static int lower_bound(List indexes,
                       int k)
{
    int low = 0, high = indexes.size() - 1;
 
    while (low < high)
    {
        int mid = (low + high) / 2;
        if (indexes.get(mid) < k)
            low = mid + 1;
        else
            high = mid;
    }
    return indexes.get(low);
}
 
// Driver code
public static void main(String[] args)
{
    int arr[] = { 1, 3, 2, 1, 2 };
 
    int n = arr.length;
 
    LIS(arr, n);
}
}
 
// This code is contributed by jithin


Python3
# Python3 implementation to
# Find the minimum concatenation
# required to get strictly Longest
# Increasing Subsequence for the
# given array with repetitive elements
from bisect import bisect_left
 
def LIS(arr, n):
   
    # ordered map containing
    # value and a vector containing
    # index of it's occurrences
    #  > m;
    m = {}
 
    # Mapping index with their
    # values in ordered map
    for i in range(n):
        m[arr[i]] = m.get(arr[i], [])
        m[arr[i]].append(i)
 
    # k refers to present
    # minimum index
    k = n
 
    # Stores the number of
    # concatenation required
    ans = 1
 
    # Iterate over map m
    for key, value in m.items():
       
        # it.second refers to the
        # vector containing all
        # corresponding indexes
 
        # it.second.back refers
        # to the last element of
        # corresponding vector
        if (value[len(value) - 1] < k):
            k = value[0]
            ans += 1
        else:
           
            # find the index of next
            # minimum element in the
            # sequence
            k = bisect_left(value, k)
 
    # Return the final
    # answer
    print(ans)
 
# Driver code
if __name__ == '__main__':
   
    arr =  [1, 3, 2, 1, 2]
    n = len(arr)
    LIS(arr, n)
 
# This code is contributed by bgangwar59


输出:
2














时间复杂度: O(n * log n)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程