Facebook Pixel

3618. Split Array by Prime Indices

MediumArrayMathNumber Theory
Leetcode Link

Problem Description

You are given an integer array nums.

Split nums into two arrays A and B using the following rule:

  • Elements at prime indices in nums must go into array A.
  • All other elements must go into array B.

Return the absolute difference between the sums of the two arrays: |sum(A) - sum(B)|.

Note: An empty array has a sum of 0.

Example: If nums = [1,2,3,4,5,6], the prime indices are 2, 3, 5, so A = [3, 4, 6], B = [1, 2, 5], and the answer is |sum([3,4,6]) - sum([1,2,5])| = |13 - 8| = 5.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

To solve the problem, notice that we need to separate elements based on whether their indices are prime numbers. For every index, if it’s a prime, its value goes into array A; otherwise, it goes to B. To figure this out quickly for all indices, we can first preprocess which numbers up to the largest possible index are prime, for example using the Sieve of Eratosthenes. Then, as we go through nums, for each index, we just check if it’s prime or not, collecting sums for the two arrays. In the end, calculating the absolute difference between the two sums gives the answer. This approach is systematic and ensures we handle all cases efficiently.

Solution Approach

To efficiently determine if each index is a prime number, we use the Sieve of Eratosthenes algorithm. The sieve preprocesses all numbers up to 10^5 (or a higher bound based on the input size), and marks whether each index is prime or not. This lets us quickly check for each index as we iterate through the input array.

Here's how the algorithm works:

  1. Sieve of Eratosthenes: Create a boolean array primes where primes[i] is True if i is a prime number, and False otherwise. Start with all entries marked as True except indices 0 and 1. Then, for every integer i starting from 2, if primes[i] is True, mark all multiples of i (except i itself) as False.

  2. Iterate through the array: For each element nums[i], check if i is a prime (using the primes array):

    • If i is prime, add nums[i] to array A's sum.
    • Otherwise, add nums[i] to array B's sum.
  3. Compute the answer: The result is the absolute value of the difference between the two sums: |sum(A) - sum(B)|.

By using a precomputed prime array, we reduce the time spent on prime checks during the main loop. The core data structure here is the boolean sieve array, and all other operations run in linear time with respect to the array size.

The implementation can be summarized by:

  • Preprocessing all prime indices using the sieve,
  • Iterating once through nums and partitioning based on index primality,
  • Returning the absolute difference of the sums.

Ready to land your dream job?

Unlock your dream job with a 2-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's use a small example: nums = [7, 8, 6, 9, 5].

Step 1: Identify prime indices.

  • The indices in this array are: 0, 1, 2, 3, 4.
  • Prime numbers up to 4 are: 2 and 3.

Step 2: Split nums based on index primality.

  • Index 0: Not prime → goes to B (nums[0] = 7)
  • Index 1: Not prime → goes to B (nums[1] = 8)
  • Index 2: Prime → goes to A (nums[2] = 6)
  • Index 3: Prime → goes to A (nums[3] = 9)
  • Index 4: Not prime → goes to B (nums[4] = 5)

Thus,

  • Array A (prime indices): [6, 9]
  • Array B (other indices): [7, 8, 5]

Step 3: Calculate the sums.

  • sum(A) = 6 + 9 = 15
  • sum(B) = 7 + 8 + 5 = 20

Step 4: Compute the absolute difference.

  • |sum(A) - sum(B)| = |15 - 20| = 5

So, for this example, the output is 5.

Solution Implementation

1# Define a limit for prime number sieve
2LIMIT = 10**5 + 10
3
4# Sieve of Eratosthenes to find prime numbers up to LIMIT
5is_prime = [True] * LIMIT
6is_prime[0] = is_prime[1] = False  # 0 and 1 are not prime
7
8# Mark multiples of each prime as non-prime
9for i in range(2, LIMIT):
10    if is_prime[i]:
11        for j in range(i * 2, LIMIT, i):
12            is_prime[j] = False
13
14from typing import List
15
16class Solution:
17    def splitArray(self, nums: List[int]) -> int:
18        # For each index, add the value if the index is prime, else subtract it.
19        # Return the absolute value of the sum
20        return abs(
21            sum(
22                num if is_prime[idx] else -num
23                for idx, num in enumerate(nums)
24            )
25        )
26
1class Solution {
2    // Maximum size for prime number calculation
3    private static final int MAX_SIZE = 100010;
4    // Array to mark prime numbers: true means prime
5    private static boolean[] isPrime = new boolean[MAX_SIZE];
6
7    // Static block to initialize the prime number sieve
8    static {
9        // Initialize all entries as true (potential primes)
10        for (int i = 0; i < MAX_SIZE; i++) {
11            isPrime[i] = true;
12        }
13        // 0 and 1 are not prime numbers
14        isPrime[0] = false;
15        isPrime[1] = false;
16
17        // Sieve of Eratosthenes to mark non-primes
18        for (int i = 2; i < MAX_SIZE; i++) {
19            if (isPrime[i]) {
20                for (int j = i * 2; j < MAX_SIZE; j += i) {
21                    isPrime[j] = false;
22                }
23            }
24        }
25    }
26
27    /**
28     * Calculate the absolute value of the sum by adding nums[i] if i is prime,
29     * and subtracting nums[i] if i is not prime.
30     * @param nums input integer array
31     * @return the absolute value of the calculated sum
32     */
33    public long splitArray(int[] nums) {
34        long total = 0;
35        // Iterate through the array
36        for (int i = 0; i < nums.length; i++) {
37            // Add or subtract based on the index's primality
38            if (isPrime[i]) {
39                total += nums[i];
40            } else {
41                total -= nums[i];
42            }
43        }
44        // Return absolute value of the result
45        return Math.abs(total);
46    }
47}
48
1#include <vector>
2#include <cstring>
3#include <cmath>
4using namespace std;
5
6// Define the maximum possible size for the sieve
7const int MAX_SIZE = 1e5 + 10;
8bool isPrime[MAX_SIZE];
9
10// Sieve of Eratosthenes to precompute prime numbers up to MAX_SIZE
11auto initializePrimes = [] {
12    memset(isPrime, true, sizeof(isPrime));
13    isPrime[0] = isPrime[1] = false;
14    for (int i = 2; i < MAX_SIZE; ++i) {
15        if (isPrime[i]) {
16            // Mark all multiples of i as non-prime
17            for (int j = i * 2; j < MAX_SIZE; j += i) {
18                isPrime[j] = false;
19            }
20        }
21    }
22    return 0;
23}(); // This lambda is executed immediately to fill isPrime[]
24
25class Solution {
26public:
27    // Method to process nums[] according to index primality
28    long long splitArray(vector<int>& nums) {
29        long long result = 0;
30        for (int i = 0; i < nums.size(); ++i) {
31            // If the index is prime, add; if not, subtract
32            result += isPrime[i] ? nums[i] : -nums[i];
33        }
34        // Return absolute value of result
35        return abs(result);
36    }
37};
38
1// Set the maximum number for sieve (limit should be larger than max possible array length)
2const MAX_SIZE = 100010;
3
4// Array to mark whether an index is a prime (true) or not (false)
5const primes: boolean[] = new Array(MAX_SIZE).fill(true);
6
7// Sieve of Eratosthenes to precompute all primes up to MAX_SIZE
8const init = (() => {
9    primes[0] = false;
10    primes[1] = false;
11    for (let i = 2; i < MAX_SIZE; i++) {
12        if (primes[i]) {
13            for (let j = i * 2; j < MAX_SIZE; j += i) {
14                primes[j] = false;
15            }
16        }
17    }
18})();
19
20/**
21 * Given an array of numbers, compute the special sum as follows:
22 * For each index, if it is prime, add nums[i], else subtract nums[i]
23 * Return the absolute value of the final result
24 * @param nums Array of numbers
25 * @returns Absolute value of the computed sum
26 */
27function splitArray(nums: number[]): number {
28    let result = 0;
29    for (let i = 0; i < nums.length; i++) {
30        // Add or subtract based on whether index is prime
31        result += primes[i] ? nums[i] : -nums[i];
32    }
33    return Math.abs(result);
34}
35

Time and Space Complexity

Ignoring the preprocessing time and space, the time complexity is O(n), where n is the length of the array nums, since the comprehension iterates through the array once. The space complexity is O(1) (excluding the given primes array), as only a constant amount of extra space is used during computation. The Sieve of Eratosthenes preprocessing (primes) has a one-time time complexity of O(m log log m) and space complexity of O(m), but these are independent of the splitArray function's per-call complexity.


Discover Your Strengths and Weaknesses: Take Our 2-Minute Quiz to Tailor Your Study Plan:

Which of the two traversal algorithms (BFS and DFS) can be used to find whether two nodes are connected?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More