Skip to content

Commit

Permalink
Optimized solution to "Prime Subtraction Operation" problem
Browse files Browse the repository at this point in the history
  • Loading branch information
dkoval committed Nov 11, 2024
1 parent 0a10e88 commit 1d4156f
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,48 @@ public boolean primeSubOperation(int[] nums) {
return true;
}
}

class PrimeSubtractionOperationRev2 implements PrimeSubtractionOperation {
// PRIMES[x] == true if x is a prime number.
// Constraints: 1 <= x <= 1000
private static final boolean[] PRIMES = primes(1001);

private static boolean[] primes(int n) {
// sieve of Eratosthenes
boolean[] primes = new boolean[n + 1];
Arrays.fill(primes, true);
primes[0] = false;
primes[1] = false;

for (int i = 2; i <= n; i++) {
if (primes[i]) {
// discard all multiples of i
for (int j = i * i; j <= n; j += i) {
primes[j] = false;
}
}
}
return primes;
}

@Override
public boolean primeSubOperation(int[] nums) {
int n = nums.length;

// Idea: to keep the array sorted in ASC order,
// try to replace it with a monotonically increasing sequence starting at 1.
// This approach, in essence, minimizes nums[i] by subtracting the biggest possible prime number.
int seqNum = 1;
for (int x : nums) {
while (seqNum < x && !PRIMES[x - seqNum]) {
seqNum++;
}
if (seqNum > x) {
return false;
}
seqNum++;
}
return true;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.github.dkoval.leetcode.challenge

import com.github.dkoval.leetcode.challenge.PrimeSubtractionOperation.PrimeSubtractionOperationRev1
import com.github.dkoval.leetcode.challenge.PrimeSubtractionOperation.PrimeSubtractionOperationRev2
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.extension.ExtensionContext
Expand All @@ -26,6 +27,18 @@ internal class PrimeSubtractionOperationTest {
Arguments.of(
intArrayOf(5, 8, 3),
false
),
Arguments.of(
intArrayOf(2, 2),
false
),
Arguments.of(
intArrayOf(4, 3, 7, 4),
false
),
Arguments.of(
intArrayOf(998, 2),
true
)
)
}
Expand All @@ -39,6 +52,16 @@ internal class PrimeSubtractionOperationTest {
PrimeSubtractionOperationRev1().test(nums, expected)
}
}

@Nested
inner class PrimeSubtractionOperationRev2Test {

@ParameterizedTest
@ArgumentsSource(InputArgumentsProvider::class)
fun `should return true if you can make nums a strictly increasing array`(nums: IntArray, expected: Boolean) {
PrimeSubtractionOperationRev2().test(nums, expected)
}
}
}

private fun PrimeSubtractionOperation.test(nums: IntArray, expected: Boolean) {
Expand Down

0 comments on commit 1d4156f

Please sign in to comment.