4064. Longest Subarray Divisible by K with At Most One Negation II
DifficultyHard
Description
You are given an integer array nums and an integer k.
A subarray is valid if its sum is divisible by k, or can become divisible by k by negating one element within that subarray.
Negating an element means replacing its value x with -x.
Return the length of the longest valid subarray. If no valid subarray exists, return 0.
A subarray is a contiguous, non-empty sequence of elements within an array.
Example 1:
Input: nums = [4,1,2], k = 3
Output: 3
Explanation:
- The sum of the entire array is 7, and
7 % 3 = 1, so it is not divisible byk = 3. - Negating
nums[2] = 2changes the sum to4 + 1 − 2 = 3, which is divisible byk. - Therefore, the entire array is a valid subarray, giving a length of 3.
Example 2:
Input: nums = [5,3,4], k = 7
Output: 2
Explanation:
- The sum of the entire array is 12, and negating any one of its elements does not make its sum divisible by 7.
- However, the subarray
[3, 4]has a sum of 7, which is divisible byk = 7without any negation. - Therefore, the longest valid subarray has a length of 2.
Example 3:
Input: nums = [2,2,5], k = 6
Output: 2
Explanation:
- The sum of the entire array is 9, and negating any one of its elements does not make its sum divisible by 6.
- The subarray
[2, 2]has a sum of 4. Negating either element changes it to[-2, 2]or[2, -2], both of which have a sum of 0. - Therefore, the longest valid subarray has a length of 2.
Constraints:
1 <= nums.length <= 105-105 <= nums[i] <= 1051 <= k <= 3000
Solutions
Solution 1: Prefix Sums
Thinking
\(n\) can be \(10^5\). Enumerating the negated index and scanning prefix sums for each choice, as in the previous problem, takes \(O(n^2)\) and does not finish in time. Here \(k\le 3000\), so there are only that many residues.
A subarray sum modulo \(k\) is the right prefix minus the left prefix. Negating an element \(x\) decreases that difference by \(2x\), so the right residue equals the left residue plus \(2(x\bmod k)\). Each left residue needs only its earliest prefix; a later index produces a shorter subarray.
Those earliest indices are handled in the order they appear. While scanning the right end, the current element supplies the residue used for negation, and every left residue that can already cover it and has not been recorded for this residue is written onto the target residue. Each pair of residues is written once, and the smallest left end stored for the right residue is the longest valid subarray ending there.
Let \(p[0]=0\) and \(p[i+1]=(p[i]+\textit{nums}[i])\bmod k\). The sum of \(\textit{nums}[L..R]\) is \(p[R+1]-p[L]\) modulo \(k\). Negating \(\textit{nums}[t]\) inside it, with \(a=\textit{nums}[t]\bmod k\), decreases the sum by \(2\textit{nums}[t]\). The subarray is valid when some \(t\in[L,R]\) satisfies
and it is also valid with no negation when \(p[R+1]\equiv p[L]\). The length is \((R+1)-L\), so a fixed right end wants the smallest left end.
\(\textit{first}[q]\) is the first prefix index whose residue is \(q\). Sort the residues that occur by \(\textit{first}\) into \(\textit{order}\). \(\textit{best}[s]\) stores the smallest left end currently known for a right prefix of residue \(s\). It starts as \(\textit{first}[s]\), or as a sentinel when that residue has not occurred. The initial values cover the case with no negation.
Scan index \(i\) from left to right and let \(a=\textit{nums}[i]\bmod k\). A pointer remembers how far each residue \(a\) has walked through \(\textit{order}\). Every residue \(q\) with \(\textit{first}[q]\le i\) can include position \(i\), so set
After negating index \(i\), a subarray that starts at \(\textit{first}[q]\) and ends at any later right end of residue \(t\) is valid. The pointer only moves forward, so each pair \((a,q)\) is handled once. Later right ends still contain \(i\), and \(\textit{best}\) keeps the smallest left end.
Let \(s=p[i+1]\). When \(\textit{best}[s]\) is not the sentinel, update the answer with \(i+1-\textit{best}[s]\). Negative values are reduced into \([0,k)\).
The time complexity is \(O(n+k^2)\) and the space complexity is \(O(n+k)\).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | |