Given an array of integers nums
and a positive integer k
, check whether it is possible to divide this array into sets of k
consecutive numbers.
Return true
if it is possible. Otherwise, return false
.
Example 1:
Input: nums = [1,2,3,3,4,4,5,6], k = 4 Output: true Explanation: Array can be divided into [1,2,3,4] and [3,4,5,6].
Example 2:
Input: nums = [3,2,1,2,3,4,3,4,5,9,10,11], k = 3 Output: true Explanation: Array can be divided into [1,2,3] , [2,3,4] , [3,4,5] and [9,10,11].
Example 3:
Input: nums = [1,2,3,4], k = 3 Output: false Explanation: Each array should be divided in subarrays of size 3.
Constraints:
1 <= k <= nums.length <= 105
1 <= nums[i] <= 109
Note: This question is the same as 846: https://leetcode.com/problems/hand-of-straights/
This problem asks whether we can partition an array into sets of k
consecutive numbers. The optimal solution uses a combination of hashing (to count element occurrences) and sorting (to efficiently find consecutive sequences).
Approach:
Counting Occurrences: We first count the occurrences of each number in the input array nums
using a hash map (dictionary in Python). This allows for efficient lookups of element frequencies.
Sorting: We sort the input array nums
. Sorting ensures that we process numbers in ascending order, making it easier to find consecutive sequences.
Greedy Approach: We iterate through the sorted array. For each number v
:
v
is present (count > 0) in the hash map:k-1
consecutive numbers (v+1
, v+2
, ..., v+k-1
) are also present and have counts greater than 0.k
consecutive numbers are found, we decrement their counts in the hash map. If a count reaches 0, we remove the entry from the map to avoid redundant checks.k
consecutive numbers is impossible, and we return false
.Success: If we successfully process all numbers in the sorted array without finding any missing consecutive numbers, it means we can partition the array as required, and we return true
.
Time Complexity:
k
is significantly smaller than n
, this is still dominated by O(n log n).Therefore, the overall time complexity is O(n log n).
Space Complexity:
Therefore, the overall space complexity is O(n).
Code Examples:
The code examples below demonstrate the solution in Python, Java, C++, and Go. They all follow the same algorithmic approach.
from collections import Counter
def isPossibleDivide(nums, k):
if len(nums) % k != 0: # Check if partition is possible
return False
count = Counter(nums)
for num in sorted(nums):
if count[num] > 0:
for i in range(num, num + k):
if count[i] == 0:
return False
count[i] -= 1
return True
import java.util.*;
class Solution {
public boolean isPossibleDivide(int[] nums, int k) {
if (nums.length % k != 0) return false;
Map<Integer, Integer> count = new HashMap<>();
for (int num : nums) {
count.put(num, count.getOrDefault(num, 0) + 1);
}
Arrays.sort(nums);
for (int num : nums) {
if (count.get(num) > 0) {
for (int i = num; i < num + k; i++) {
if (count.getOrDefault(i, 0) == 0) return false;
count.put(i, count.get(i) - 1);
}
}
}
return true;
}
}
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
bool isPossibleDivide(vector<int>& nums, int k) {
if (nums.size() % k != 0) return false;
map<int, int> count;
for (int num : nums) {
count[num]++;
}
sort(nums.begin(), nums.end());
for (int num : nums) {
if (count[num] > 0) {
for (int i = num; i < num + k; i++) {
if (count.count(i) == 0 || count[i] == 0) return false;
count[i]--;
}
}
}
return true;
}
import (
"sort"
)
func isPossibleDivide(nums []int, k int) bool {
if len(nums)%k != 0 {
return false
}
count := make(map[int]int)
for _, num := range nums {
count[num]++
}
sort.Ints(nums)
for _, num := range nums {
if count[num] > 0 {
for i := num; i < num+k; i++ {
if count[i] == 0 {
return false
}
count[i]--
}
}
}
return true
}
This detailed explanation, along with the code examples, provides a comprehensive understanding of how to solve the "Divide Array in Sets of K Consecutive Numbers" problem efficiently. Remember to handle the edge case where the array length is not divisible by k
.