Welcome to Subscribe On Youtube
2344. Minimum Deletions to Make Array Divisible
Description
You are given two positive integer arrays nums and numsDivide. You can delete any number of elements from nums.
Return the minimum number of deletions such that the smallest element in nums divides all the elements of numsDivide. If this is not possible, return -1.
Note that an integer x divides y if y % x == 0.
Example 1:
Input: nums = [2,3,2,4,3], numsDivide = [9,6,9,3,15] Output: 2 Explanation: The smallest element in [2,3,2,4,3] is 2, which does not divide all the elements of numsDivide. We use 2 deletions to delete the elements in nums that are equal to 2 which makes nums = [3,4,3]. The smallest element in [3,4,3] is 3, which divides all the elements of numsDivide. It can be shown that 2 is the minimum number of deletions needed.
Example 2:
Input: nums = [4,3,6], numsDivide = [8,2,6,10] Output: -1 Explanation: We want the smallest element in nums to divide all the elements of numsDivide. There is no way to delete elements from nums to allow this.
Constraints:
1 <= nums.length, numsDivide.length <= 1051 <= nums[i], numsDivide[i] <= 109
Solutions
Solution 1: Sorting
If an element divides all elements of the array numsDivide, then this element is a factor of the greatest common divisor of all $numsDivide[i]$ $x$. Therefore, we can first find the greatest common divisor $x$ of numsDivide.
Next, sort the array nums, then traverse the array nums from beginning to end, find the first element that is a factor of the greatest common divisor $x$, and return the current element subscript.
Time complexity $O(m + \log M + n \times \log n)$, where $n$ and $m$ are the lengths of the arrays nums and numsDivide respectively, and $M$ is the maximum value in the array numsDivide.
In fact, we can also directly traverse the array nums without sorting the array nums to find the smallest element that can divide $x$. Then we traverse the array nums again and count the number of elements less than or equal to this element.
Time complexity $O(m + \log M + n)$.
Solution 2
This implementation uses sorting. It traverses the relevant values and updates its state as each value is processed. Ordering the data first makes the subsequent comparisons deterministic. After all required states have been considered, the maintained result is returned.
Solution 3
This implementation follows the required operations directly. It traverses the relevant values and updates its state as each value is processed. After all required states have been considered, the maintained result is returned.
-
class Solution { public int minOperations(int[] nums, int[] numsDivide) { int x = 0; for (int v : numsDivide) { x = gcd(x, v); } Arrays.sort(nums); for (int i = 0; i < nums.length; ++i) { if (x % nums[i] == 0) { return i; } } return -1; } private int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } } // Solution 2 class Solution { public int minOperations(int[] nums, int[] numsDivide) { int x = 0; for (int v : numsDivide) { x = gcd(x, v); } int y = 1 << 30; for (int v : nums) { if (x % v == 0) { y = Math.min(y, v); } } if (y == 1 << 30) { return -1; } int ans = 0; for (int v : nums) { if (v < y) { ++ans; } } return ans; } private int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } } -
class Solution { public: int minOperations(vector<int>& nums, vector<int>& numsDivide) { int x = 0; for (int& v : numsDivide) { x = gcd(x, v); } sort(nums.begin(), nums.end()); for (int i = 0; i < nums.size(); ++i) { if (x % nums[i] == 0) { return i; } } return -1; } }; // Solution 2 class Solution { public: int minOperations(vector<int>& nums, vector<int>& numsDivide) { int x = 0; for (int& v : numsDivide) { x = gcd(x, v); } int y = 1 << 30; for (int& v : nums) { if (x % v == 0) { y = min(y, v); } } if (y == 1 << 30) { return -1; } int ans = 0; for (int& v : nums) { ans += v < y; } return ans; } }; -
class Solution: def minOperations(self, nums: List[int], numsDivide: List[int]) -> int: x = numsDivide[0] for v in numsDivide[1:]: x = gcd(x, v) nums.sort() for i, v in enumerate(nums): if x % v == 0: return i return -1 # Solution 2 class Solution: def minOperations(self, nums: List[int], numsDivide: List[int]) -> int: x = gcd(*numsDivide) nums.sort() return next((i for i, v in enumerate(nums) if x % v == 0), -1) # Solution 3 class Solution: def minOperations(self, nums: List[int], numsDivide: List[int]) -> int: x = gcd(*numsDivide) y = min((v for v in nums if x % v == 0), default=0) return sum(v < y for v in nums) if y else -1 -
func minOperations(nums []int, numsDivide []int) int { x := 0 for _, v := range numsDivide { x = gcd(x, v) } sort.Ints(nums) for i, v := range nums { if x%v == 0 { return i } } return -1 } func gcd(a, b int) int { if b == 0 { return a } return gcd(b, a%b) } // Solution 2 func minOperations(nums []int, numsDivide []int) int { x := 0 for _, v := range numsDivide { x = gcd(x, v) } y := 1 << 30 for _, v := range nums { if x%v == 0 { y = min(y, v) } } if y == 1<<30 { return -1 } ans := 0 for _, v := range nums { if v < y { ans++ } } return ans } func gcd(a, b int) int { if b == 0 { return a } return gcd(b, a%b) }