📌  相关文章
📜  检查给定的数组是否可以分成K个增加的连续整数的子序列

📅  最后修改于: 2022-05-13 01:56:06.628000             🧑  作者: Mango

检查给定的数组是否可以分成K个增加的连续整数的子序列

给定一个由N个整数组成的数组arr[]和一个正整数K ,任务是检查是否可以将数组分成K个连续整数的递增子序列,这样每个元素只能在一个子序列中起作用。

示例

方法:上述问题可以通过使用二分搜索的贪心方法来解决。可以观察到,对于任何整数arr[i] ,最优选择是在子数组 arr[i+1, N)中选择arr[i] + 1的最小索引。使用此观察结果,请按照以下步骤解决给定问题:

  • 如果K不是N的除数,则不存在可能的所需子序列集。因此,打印No
  • 将每个整数的索引存储在 Set 数据结构中。它可以使用具有键集对结构的映射有效地存储。
  • 维护一个已访问数组以跟踪已包含在子序列中的索引。
  • 对 [0, N) 范围内的每个 i 进行迭代,如果当前索引处的整数尚未被访问,则执行以下步骤:
    • 使用upper_bound函数,在[i+1, N)范围内找到arr[i] + 1的最小索引,并用它更新当前子序列的最后一个元素的值。
    • 重复上述步骤K-1次,直到创建了K个整数的完整子序列。
  • 在任何迭代期间,如果所需的整数不存在,则不存在任何可能的所需子序列集。因此,打印No 。否则,打印Yes

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to check if the array can
// be divided into subsequences of K
// consecutive integers in increasing order
bool isPossible(vector nums, int K)
{
    int N = nums.size();
 
    // If N is not divisible by K or
    // K>N, no possible set of required
    // subsequences exist
    if (N % K != 0 || K > N) {
        return false;
    }
 
    // Stores the indices of each
    // element in a set
    map > idx;
 
    // Stores the index of each number
    for (int i = 0; i < nums.size(); i++) {
        idx[nums[i]].insert(i);
    }
 
    // Stores if the integer at current
    // index is already included in
    // a subsequence
    int visited[N] = { 0 };
 
    // Stores the count of total
    // visited elements
    int total_visited = 0;
 
    for (int i = 0; i < nums.size(); i++) {
 
        // If current integer is already
        // in a subsequence
        if (visited[i]) {
            continue;
        }
 
        // Stores the value of last element
        // of the current subsequence
        int num = nums[i];
 
        // Stores the index of last element
        // of the current subsequence
        int last_index = i;
 
        // Mark Visited
        visited[i] = 1;
 
        // Increment the visited count
        total_visited++;
 
        // Find the next K-1 elements of the
        // subsequence starting from index i
        for (int j = num + 1; j < num + K; j++) {
 
            // No valid index found
            if (idx[j].size() == 0) {
                return false;
            }
 
            // Find index of j such that it
            // is greater than last_index
            auto it = idx[j].upper_bound(last_index);
 
            // if no such index found,
            // return false
            if (it == idx[j].end()
                || *it <= last_index) {
                return false;
            }
 
            // Update last_index
            last_index = *it;
 
            // Mark current index as visited
            visited[last_index] = 1;
 
            // Increment total_visited by 1
            total_visited++;
 
            // Remove the index from set because
            // it has been already used
            idx[j].erase(it);
        }
    }
 
    // Return the result
    return total_visited == N;
}
 
// Driver Code
int main()
{
    vector arr = { 4, 3, 1, 2 };
    int K = 2;
    cout << (isPossible(arr, K) ? "Yes" : "No");
 
    return 0;
}


Python3
# Python3 program for the above approach
 
# Function to check if the array can
# be divided into subsequences of K
# consecutive integers in increasing order
def isPossible(nums, K):
    N = len(nums)
     
    # If N is not divisible by K or
    # K>N, no possible set of required
    # subsequences exist
    if (N % K != 0 or K > N):
        return False
       
     # Stores the indices of each
    # element in a set
    idx = {}
     
     # Stores the index of each number
    for i in range(N):
        if nums[i] in idx:
            idx[nums[i]].add(i)
        else:
            idx[nums[i]] = {i}
             
    # Stores if the integer at current
    # index is already included in
    # a subsequence
    visited = [0]*N
     
    # Stores the count of total
    # visited elements
    total_visited = 0
    for i in range(N):
       
        # If current integer is already
        # in a subsequence
        if(visited[i]):
            continue
             
        # Stores the value of last element
        # of the current subsequence
        num = nums[i]
         
        # Stores the index of last element
        # of the current subsequence
        last_index = i
         
        # Marked visited
        visited[i] = 1
         
         # Increment the visited count
        total_visited += 1
         
        # Find the next K-1 elements of the
        # subsequence starting from index i
        for j in range(num+1, num+K):
           
           # No valid index found
            if j not in idx or len(idx[j]) == 0:
                return False
            temp = False
             
            # Find index of j such that it
            # is greater than last_index
            for it in idx[j]:
                if it > last_index:
                    last_index = it
                    temp = True
                    break
            if(temp == False):
                return False
               
            # Update last index
            visited[last_index] = 1
             
            # Mark current index as visited
             
             # Increment total_visited by 1
            total_visited += 1
             
            # Remove the index
            idx[j].remove(it)
             
            # Return the result
    return total_visited == N
 
# Driver code
arr = [4, 3, 1, 2]
K = 2
if (isPossible(arr, K)):
    print("Yes")
else:
    print("No")
     
# This code is contributed by parthmanchanda81


Javascript



输出:
No

时间复杂度: O(N*log N)
辅助空间: O(N)