703326. Smallest Subarray GCD
Medium
Smallest Subarray GCD
Summary
Find the smallest subarray with a Greatest Common Divisor (GCD) equal to k. Given an array of integers, find the smallest contiguous subarray whose GCD is equal to k.
Detailed Explanation
To solve this problem, we can use a segment tree data structure. The idea is to maintain a segment tree where each node represents the GCD of its corresponding range in the original array.
Here's a step-by-step breakdown:
- Initialize an empty segment tree.
- Traverse the input array and for each element
x, update the segment tree as follows:- If the current node represents a range that includes
x, calculate the new GCD by updating the GCD of the current node withx. - Otherwise, create a new node in the segment tree representing the range
[start, x](wherestartis the start index of the current node) and update its value to be the GCD of this new range.
- If the current node represents a range that includes
- Once the segment tree is constructed, traverse it to find the smallest subarray with a GCD equal to
k. This can be done by iterating through the nodes in the segment tree and checking if the GCD of each node equalsk.
Time complexity: O(n log n) where n is the size of the input array.
Space complexity: O(n) for the segment tree.
Optimized Solutions
Java
class SmallestSubarrayGCD {
public static int findSmallestSubarray(int[] arr, int k) {
int n = arr.length;
SegmentTree tree = new SegmentTree(arr);
int ans = Integer.MAX_VALUE;
for (int i = 0; i < n; i++) {
if (tree.query(i, i) == k) {
ans = Math.min(ans, i - tree.getStart());
}
}
return ans;
}
static class SegmentTree {
int[] tree;
int start;
public SegmentTree(int[] arr) {
int n = arr.length;
tree = new int[n + 1];
start = 0;
buildTree(arr);
}
void buildTree(int[] arr) {
for (int i = n; i > 0; i--) {
tree[i] = gcd(tree[i - 1], arr[i - 1]);
}
}
int query(int l, int r) {
return query(r) - query(l);
}
int query(int i) {
int ans = tree[i];
while (i > 0) {
ans = gcd(ans, tree[i - 1]);
i--;
}
return ans;
}
int gcd(int a, int b) {
if (b == 0) {
return a;
}
return gcd(b, a % b);
}
int getStart() {
for (int i = tree.length - 1; i > 0; i--) {
if (tree[i] == 1) {
return i;
}
}
return 0;
}
}
}