diff --git a/Medium/3876.Construct-Uniform-Parity-Array-II/description.md b/Medium/3876.Construct-Uniform-Parity-Array-II/description.md new file mode 100644 index 0000000..ff0d633 --- /dev/null +++ b/Medium/3876.Construct-Uniform-Parity-Array-II/description.md @@ -0,0 +1,55 @@ +# 3876. Construct Uniform Parity Array II + +You are given an array `nums1` of `n` **distinct** integers. + +You want to construct another array `nums2` of length `n` such that the elements +in `nums2` are either **all odd or all even**. + +For each index `i`, you must choose **exactly one** of the following (in any +order): + +- `nums2[i] = nums1[i]` +- `nums2[i] = nums1[i] - nums1[j]`, for an index `j != i`, such that + `nums1[i] - nums1[j] >= 1` + +Return `true` if it is possible to construct such an array, otherwise return +`false`. + +## Example 1 + +```text +Input: nums1 = [1,4,7] +Output: true +Explanation: +- Set nums2[0] = nums1[0] = 1. +- Set nums2[1] = nums1[1] - nums1[0] = 4 - 1 = 3. +- Set nums2[2] = nums1[2] = 7. +- nums2 = [1, 3, 7], and all elements are odd. Thus, the answer is true. +``` + +## Example 2 + +```text +Input: nums1 = [2,3] +Output: false +Explanation: +It is not possible to construct nums2 such that all elements have the same +parity. Thus, the answer is false. +``` + +## Example 3 + +```text +Input: nums1 = [4,6] +Output: true +Explanation: +- Set nums2[0] = nums1[0] = 4. +- Set nums2[1] = nums1[1] = 6. +- nums2 = [4, 6], and all elements are even. Thus, the answer is true. +``` + +## Constraints + +- `1 <= n == nums1.length <= 10^5` +- `1 <= nums1[i] <= 10^9` +- `nums1` consists of distinct integers. diff --git a/Medium/3876.Construct-Uniform-Parity-Array-II/solution.md b/Medium/3876.Construct-Uniform-Parity-Array-II/solution.md new file mode 100644 index 0000000..e2d3303 --- /dev/null +++ b/Medium/3876.Construct-Uniform-Parity-Array-II/solution.md @@ -0,0 +1,170 @@ +# Intuition + +The actual values of `nums2` never matter — only their parity. And subtraction +behaves very simply on parity: `a - b` is even exactly when `a` and `b` agree in +parity, and odd exactly when they differ. So each index has at most two reachable +parities, and the whole question becomes whether some single parity is reachable +by every index at once. + +Working through the two targets separately collapses the problem to a single +comparison: **is the smallest element odd?** + +# Approach: Parity of the Minimum + +Handle the two possible targets independently. + +## Target "all even" + +Index `i` can end up even in two ways: keep `nums1[i]` when it is already even, or +subtract some `nums1[j]` of the **same** parity with `nums1[j] < nums1[i]`. + +Now look at the **smallest odd** element, if one exists. Keeping it leaves it odd, +and making it even needs a smaller odd element — which by definition does not +exist. So that index can never be made even. + +Therefore all-even is achievable **only when `nums1` contains no odd element at +all**, in which case every index is simply kept as is. That is exactly the +`all(num & 1 == 0)` test. + +## Target "all odd" + +Index `i` can end up odd by keeping an already-odd `nums1[i]`, or by subtracting +some `nums1[j]` of the **opposite** parity with `nums1[j] < nums1[i]`. So every +even element needs an odd element strictly below it. + +This is where the minimum decides everything, and the **distinct** guarantee is +what makes it clean: + +- **If the minimum is odd**, it is strictly smaller than every other element. Each + even element can subtract it and flip to odd, while odd elements are kept. All-odd + succeeds. That is the `min & 1 == 1` test. +- **If the minimum is even**, that element itself needs an odd value strictly below + it — impossible, since nothing is below the minimum. All-odd fails. + +## Putting it together + +$$\text{answer} = (\min(nums_1) \bmod 2 = 1) \;\lor\; (\text{every element is even})$$ + +Read the other way round, the answer is `false` in exactly one situation: **the +minimum is even and at least one odd element exists.** Verified equivalent to the +formula on the whole test corpus. + +Note the two branches cannot both be true: if the minimum is odd then an odd +element exists, so "every element is even" is false. The `||` is a genuine case +split, not a redundancy. + +## Why no pairing or ordering work is needed + +It is tempting to expect a matching problem — which `j` should each `i` subtract? +But when the minimum is odd, *every* even index can use that same minimum, and +nothing prevents reusing one `j` across many `i` values. The problem only forbids +`j == i`, and the minimum is never its own index among the even elements because +it is odd. So one element serves as the universal donor and no assignment step +survives. + +# Worked examples + +## `nums1 = [1,4,7]` → `true` + +The minimum is `1`, which is odd, so the first branch fires immediately. +Constructing it explicitly: `4` subtracts the minimum to give `4 - 1 = 3`, while +`1` and `7` are kept, producing `[1, 3, 7]` — all odd. This matches the +statement's walkthrough. + +## `nums1 = [2,3]` → `false` + +The minimum is `2`, which is even, so all-odd is out: `2` would need an odd value +below it and there is none. All-even is out too, because `3` is odd and has no +smaller odd element to subtract. Both targets fail. + +## `nums1 = [4,6]` → `true` + +The minimum `4` is even, so the first branch fails, but every element is even and +the second branch succeeds — keep both, giving `[4, 6]`. + +## `nums1 = [2,3,5]` → `false` + +A useful contrast with Example 1. The minimum `2` is even, so all-odd fails at +index `0`. And `3` is odd, so all-even fails at the smallest odd. Adding more odd +elements above the even minimum never helps. + +## `nums1 = [7]` → `true` + +With `n = 1` no valid `j` exists, so `nums2 = nums1` is forced. A single element is +trivially uniform. Both branches cover it: an odd single element passes the +minimum test, and an even single element passes the all-even test. + +# Complexity + +- Time complexity: $$O(n)$$, where `n` is the length of `nums1` — one pass for the + minimum and at most one more for the parity scan. +- Space complexity: $$O(1)$$ — only the running minimum and a boolean. + +Short-circuiting helps in practice: when the minimum is odd the second scan is +skipped entirely, and the `all` / `ContainsFunc` scan stops at the first odd +element it meets. + +# Code + +## Go + +```go +import "slices" + +func uniformArray(nums1 []int) bool { + return slices.Min(nums1) & 1 == 1 || !slices.ContainsFunc(nums1, func(num int) bool { + return num % 2 == 1 + }) +} +``` + +`slices.Min` and `slices.ContainsFunc` both arrived in **Go 1.21**. The double +negative — "not contains an odd" — is how `slices` spells "all are even", since +the package offers no `AllFunc`. + +## Rust + +```rust +impl Solution { + pub fn uniform_array(nums1: Vec) -> bool { + let min_num = nums1.iter().min().unwrap_or(&i32::MAX); + min_num & 1 == 1 || nums1.iter().all(|&num| (num & 1) == 0) + } +} +``` + +`min_num` is a `&i32`, and `&i32 & 1` compiles because the operator traits are +implemented for references — no explicit deref needed. The `unwrap_or(&i32::MAX)` +fallback only matters for an empty input, which the constraints exclude; it would +return `true`, since `i32::MAX` is `2147483647` and therefore odd. + +## Python + +```python +class Solution: + def uniformArray(self, nums1: list[int]) -> bool: + return min(nums1) & 1 == 1 or all(num & 1 == 0 for num in nums1) +``` + +The generator inside `all` short-circuits on the first odd element, so the second +branch costs nothing once a counterexample appears. + +# Test cases + +| `nums1` | minimum | any odd? | answer | branch that decides | +| --- | --- | --- | --- | --- | +| `[1,4,7]` | `1` odd | yes | `true` | minimum is odd | +| `[2,3]` | `2` even | yes | `false` | neither branch | +| `[4,6]` | `4` even | no | `true` | all even | +| `[2,3,5]` | `2` even | yes | `false` | neither branch | +| `[7]` | `7` odd | yes | `true` | minimum is odd, `n = 1` | +| `[8]` | `8` even | no | `true` | all even, `n = 1` | +| `[2,4,6,7]` | `2` even | yes | `false` | one odd above an even minimum | + +All three implementations were checked against a brute force that computes, for +each index, the set of parities it can reach — keeping the value, or subtracting +any other element that leaves a positive result — and then asks whether some +parity is reachable at every index simultaneously. The corpus was **6384** cases: +the three examples, every distinct subset of `1..9` of size 1 to 5 (exhaustive), +and 6000 random distinct-valued arrays. Go, Rust and Python agreed with the +reference on every case. diff --git a/README.md b/README.md index e7704bc..e41d938 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Easy/350.Intersection-of-Two-Arrays-II/ ## Solutions index -Total: **209** problems with at least one solution file. +Total: **210** problems with at least one solution file. Solution links use variant names when multiple approaches or languages exist (`main` = `solution.md`, others = `solution-.md`). @@ -82,7 +82,7 @@ Solution links use variant names when multiple approaches or languages exist (`m | 3754. Concatenate Non-Zero Digits and Multiply by Sum I | [Link](https://leetcode.com/problems/concatenate-non-zero-digits-and-multiply-by-sum-i/) | [main](Easy/3754.Concatenate-Non-Zero-Digits-and-Multiply-by-Sum-I/solution.md) | | 3875. Construct Uniform Parity Array I | [Link](https://leetcode.com/problems/construct-uniform-parity-array-i/) | [main](Easy/3875.Construct-Uniform-Parity-Array-I/solution.md) | -### Medium (121) +### Medium (122) | Problem | LeetCode | Solution | | -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -207,6 +207,7 @@ Solution links use variant names when multiple approaches or languages exist (`m | 3702. Longest Subsequence With Non-Zero Bitwise XOR | [Link](https://leetcode.com/problems/longest-subsequence-with-non-zero-bitwise-xor/) | [main](Medium/3702.Longest-Subsequence-With-Non-Zero-Bitwise-XOR/solution.md) | | 3756. Concatenate Non-Zero Digits and Multiply by Sum II | [Link](https://leetcode.com/problems/concatenate-non-zero-digits-and-multiply-by-sum-ii/) | [main](Medium/3756.Concatenate-Non-Zero-Digits-and-Multiply-by-Sum-II/solution.md) | | 3867. Sum of GCD of Formed Pairs | [Link](https://leetcode.com/problems/sum-of-gcd-of-formed-pairs/) | [main](Medium/3867.Sum-of-GCD-of-Formed-Pairs/solution.md) | +| 3876. Construct Uniform Parity Array II | [Link](https://leetcode.com/problems/construct-uniform-parity-array-ii/) | [main](Medium/3876.Construct-Uniform-Parity-Array-II/solution.md) | ### Hard (34) diff --git a/SUMMARY.md b/SUMMARY.md index f350c78..126c557 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -198,6 +198,7 @@ * [3702. Longest Subsequence With Non Zero Bitwise XOR](Medium/3702.Longest-Subsequence-With-Non-Zero-Bitwise-XOR/solution.md) * [3756. Concatenate Non Zero Digits and Multiply by Sum II](Medium/3756.Concatenate-Non-Zero-Digits-and-Multiply-by-Sum-II/solution.md) * [3867. Sum of GCD of Formed Pairs](Medium/3867.Sum-of-GCD-of-Formed-Pairs/solution.md) +* [3876. Construct Uniform Parity Array II](Medium/3876.Construct-Uniform-Parity-Array-II/solution.md) ## Hard diff --git a/_sidebar.md b/_sidebar.md index c652dab..81ca280 100644 --- a/_sidebar.md +++ b/_sidebar.md @@ -193,6 +193,7 @@ - [3702. Longest Subsequence With Non Zero Bitwise XOR](Medium/3702.Longest-Subsequence-With-Non-Zero-Bitwise-XOR/solution.md) - [3756. Concatenate Non Zero Digits and Multiply by Sum II](Medium/3756.Concatenate-Non-Zero-Digits-and-Multiply-by-Sum-II/solution.md) - [3867. Sum of GCD of Formed Pairs](Medium/3867.Sum-of-GCD-of-Formed-Pairs/solution.md) + - [3876. Construct Uniform Parity Array II](Medium/3876.Construct-Uniform-Parity-Array-II/solution.md) - Hard - [11. Container With Most Water](Hard/11.Container-With-Most-Water/solution.md) - [23. Merge k Sorted Lists](Hard/23.Merge-k-Sorted-Lists/solution.md)