Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.
Given an integer array nums, find the number of subsequences of size 5 of nums with a unique middle mode.
Since the answer may be very large, return it modulo 109 + 7.
A mode of a sequence of numbers is defined as the element that appears the maximum number of times in the sequence.
A sequence of numbers contains a unique mode if it has only one mode.
A sequence of numbers seq of size 5 contains a unique middle mode if the middle element (seq[2]) is a unique mode.
Example 1:
Input: nums = [1,1,1,1,1,1]
Output: 6
Explanation:
[1, 1, 1, 1, 1] is the only subsequence of size 5 that can be formed, and it has a unique middle mode of 1. This subsequence can be formed in 6 different ways, so the output is 6.
Example 2:
Input: nums = [1,2,2,3,3,4]
Output: 4
Explanation:
[1, 2, 2, 3, 4] and [1, 2, 3, 3, 4] each have a unique middle mode because the number at index 2 has the greatest frequency in the subsequence. [1, 2, 2, 3, 3] does not have a unique middle mode because 2 and 3 appear twice.
Example 3:
Input: nums = [0,1,2,3,4,5,6,7,8]
Output: 0
Explanation:
There is no subsequence of length 5 with a unique middle mode.
Constraints:
5 <= nums.length <= 1000-109 <= nums[i] <= 109Problem summary: Given an integer array nums, find the number of subsequences of size 5 of nums with a unique middle mode. Since the answer may be very large, return it modulo 109 + 7. A mode of a sequence of numbers is defined as the element that appears the maximum number of times in the sequence. A sequence of numbers contains a unique mode if it has only one mode. A sequence of numbers seq of size 5 contains a unique middle mode if the middle element (seq[2]) is a unique mode.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Hash Map · Math
[1,1,1,1,1,1]
[1,2,2,3,3,4]
[0,1,2,3,4,5,6,7,8]
subsequences-with-a-unique-middle-mode-ii)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3395: Subsequences with a Unique Middle Mode I
class Solution {
public int subsequencesWithMiddleMode(int[] nums) {
int n = nums.length;
long ans = 0;
Map<Integer, Integer> left = new HashMap<>();
Map<Integer, Integer> right = new HashMap<>();
for (int i = 0; i < 2; ++i)
left.merge(nums[i], 1, Integer::sum);
for (int i = 2; i < n; ++i)
right.merge(nums[i], 1, Integer::sum);
for (int i = 2; i < n - 2; ++i) {
final int num = nums[i];
if (right.merge(num, -1, Integer::sum) == 0)
right.remove(num);
final int leftCount = left.getOrDefault(num, 0);
final int rightCount = right.getOrDefault(num, 0);
final int leftOther = i - leftCount;
final int rightOther = n - 1 - i - rightCount;
// count[mode] = 5 -- [a a] a [a a]
ans = (ans + nC2(leftCount) * nC2(rightCount)) % MOD;
// count[mode] = 4 -- [a a] a [a ?]
ans = (ans + nC2(leftCount) * rightCount % MOD * rightOther % MOD) % MOD;
// count[mode] = 4 -- [a ?] a [a a]
ans = (ans + leftCount * leftOther % MOD * nC2(rightCount) % MOD) % MOD;
// count[mode] = 3 -- [a a] a [? ?]
ans = (ans + nC2(leftCount) * nC2(rightOther) % MOD) % MOD;
// count[mode] = 3 -- [? ?] a [a a]
ans = (ans + nC2(leftOther) * nC2(rightCount) % MOD) % MOD;
// count[mode] = 3 -- [a ?] a [a ?]
ans = (ans + leftCount * leftOther % MOD * rightCount % MOD * rightOther % MOD) % MOD;
// count[mode] = 2 -- [a ?] a [? ?]
ans = (ans + leftCount * calc(num, leftOther, rightOther, left, right) % MOD) % MOD;
// count[mode] = 2 -- [? ?] a [a ?]
ans = (ans + rightCount * calc(num, rightOther, leftOther, right, left) % MOD) % MOD;
// Update left map
left.merge(num, 1, Integer::sum);
}
return (int) (ans % MOD);
}
private static final int MOD = 1_000_000_007;
// Returns C(n, 2)
private long nC2(long n) {
return n * (n - 1) / 2 % MOD;
}
// Returns the count of subsequences that have 'a' as the middle number, where
// invalid subsequences are excluded
private long calc(int a, long other1, long other2, Map<Integer, Integer> count1,
Map<Integer, Integer> count2) {
// [a ?] a [? ?]
long res = other1 * nC2(other2) % MOD;
for (Map.Entry<Integer, Integer> entry : count1.entrySet()) {
final int b = entry.getKey();
final long b1 = entry.getValue();
if (b == a)
continue;
final long b2 = count2.getOrDefault(b, 0);
// Exclude triples -- [a b] a [b b]
res = (res - b1 * nC2(b2) % MOD + MOD) % MOD;
// Exclude doubles -- [a b] a [b ?]
res = (res - b1 * b2 % MOD * (other2 - b2) % MOD + MOD) % MOD;
}
for (Map.Entry<Integer, Integer> entry : count2.entrySet()) {
final int b = entry.getKey();
final long b2 = entry.getValue();
if (b == a)
continue;
final long b1 = count1.getOrDefault(b, 0);
// Exclude doubles -- [a ?] a [b b]
res = (res - (other1 - b1) * nC2(b2) % MOD + MOD) % MOD;
}
return res;
}
}
// Accepted solution for LeetCode #3395: Subsequences with a Unique Middle Mode I
package main
import (
"slices"
"sort"
)
// https://space.bilibili.com/206214
func comb2(num int) int {
return num * (num - 1) / 2
}
func subsequencesWithMiddleMode(nums []int) int {
n := len(nums)
ans := n * (n - 1) * (n - 2) * (n - 3) * (n - 4) / 120 // 所有方案数
suf := map[int]int{}
for _, num := range nums {
suf[num]++
}
pre := make(map[int]int, len(suf)) // 预分配空间
var cp, cs, ps, p2s, ps2 int
for _, c := range suf {
cs += comb2(c)
}
// 枚举 x,作为子序列正中间的数
for left, x := range nums[:n-2] {
suf[x]--
px := pre[x]
sx := suf[x]
cs -= sx
ps -= px
p2s -= px * px
ps2 -= (sx*2 + 1) * px
right := n - 1 - left
ans -= comb2(left-px) * comb2(right-sx)
ans -= (cp - comb2(px)) * sx * (right - sx)
ans -= (cs - comb2(sx)) * px * (left - px)
ans -= ((ps-px*sx)*(right-sx) - (ps2 - px*sx*sx)) * px
ans -= ((ps-px*sx)*(left-px) - (p2s - px*px*sx)) * sx
cp += px
ps += sx
ps2 += sx * sx
p2s += (px*2 + 1) * sx
pre[x]++
}
return ans % 1_000_000_007
}
func subsequencesWithMiddleMode2(nums []int) int {
n := len(nums)
ans := n * (n - 1) * (n - 2) * (n - 3) * (n - 4) / 120 // 所有方案数
suf := map[int]int{}
for _, num := range nums {
suf[num]++
}
pre := make(map[int]int, len(suf)) // 预分配空间
// 枚举 x,作为子序列正中间的数
for left, x := range nums[:n-2] {
suf[x]--
if left > 1 {
right := n - 1 - left
preX, sufX := pre[x], suf[x]
// 不合法:只有一个 x
ans -= comb2(left-preX) * comb2(right-sufX)
// 不合法:只有两个 x,且至少有两个 y(y != x)
for y, sufY := range suf { // 注意 sufY 可能是 0
if y == x {
continue
}
preY := pre[y]
// 左边有两个 y,右边有一个 x,即 yy x xz(z 可以等于 y)
ans -= comb2(preY) * sufX * (right - sufX)
// 右边有两个 y,左边有一个 x,即 zx x yy(z 可以等于 y)
ans -= comb2(sufY) * preX * (left - preX)
// 左右各有一个 y,另一个 x 在左边,即 xy x yz(z != y)
ans -= preY * sufY * preX * (right - sufX - sufY)
// 左右各有一个 y,另一个 x 在右边,即 zy x xy(z != y)
ans -= preY * sufY * sufX * (left - preX - preY)
}
}
pre[x]++
}
return ans % 1_000_000_007
}
func subsequencesWithMiddleMode3(nums []int) int {
n := len(nums)
ans := n * (n - 1) * (n - 2) * (n - 3) * (n - 4) / 120 // 所有方案数
a := slices.Clone(nums)
slices.Sort(a)
a = slices.Compact(a)
for i, x := range nums {
nums[i] = sort.SearchInts(a, x)
}
suf := make([]int, len(a))
for _, x := range nums {
suf[x]++
}
pre := make([]int, len(a))
// 枚举 x,作为子序列正中间的数
for left, x := range nums[:n-2] {
suf[x]--
if left > 1 {
right := n - 1 - left
preX, sufX := pre[x], suf[x]
// 不合法:只有一个 x
ans -= comb2(left-preX) * comb2(right-sufX)
// 不合法:只有两个 x,且至少有两个 y(y != x)
for y, sufY := range suf { // 注意 sufY 可能是 0
if y == x {
continue
}
preY := pre[y]
// 左边有两个 y,右边有一个 x,即 yy x xz(z 可以等于 y)
ans -= comb2(preY) * sufX * (right - sufX)
// 右边有两个 y,左边有一个 x,即 zx x yy(z 可以等于 y)
ans -= comb2(sufY) * preX * (left - preX)
// 左右各有一个 y,另一个 x 在左边,即 xy x yz(z != y)
ans -= preY * sufY * preX * (right - sufX - sufY)
// 左右各有一个 y,另一个 x 在右边,即 zy x xy(z != y)
ans -= preY * sufY * sufX * (left - preX - preY)
}
}
pre[x]++
}
return ans % 1_000_000_007
}
# Accepted solution for LeetCode #3395: Subsequences with a Unique Middle Mode I
class Solution:
def __init__(self):
self.MOD = 1_000_000_007
def subsequencesWithMiddleMode(self, nums: list[int]) -> int:
n = len(nums)
ans = 0
left = collections.Counter()
right = collections.Counter()
for i in range(2):
left[nums[i]] += 1
for i in range(2, n):
right[nums[i]] += 1
for i in range(2, n - 2):
num = nums[i]
right[num] -= 1
if right[num] == 0:
del right[num]
leftCount = left[num]
rightCount = right[num]
leftOther = i - leftCount
rightOther = n - 1 - i - rightCount
# count[mode] = 5 -- [a a] a [a a]
ans += math.comb(leftCount, 2) * math.comb(rightCount, 2)
# count[mode] = 4 -- [a a] a [a ?]
ans += math.comb(leftCount, 2) * rightCount * rightOther
# count[mode] = 4 -- [a ?] a [a a]
ans += leftCount * leftOther * math.comb(rightCount, 2)
# count[mode] = 3 -- [a a] a [? ?]
ans += math.comb(leftCount, 2) * math.comb(rightOther, 2)
# count[mode] = 3 -- [? ?] a [a a]
ans += math.comb(leftOther, 2) * math.comb(rightCount, 2)
# count[mode] = 3 -- [a ?] a [a ?]
ans += leftCount * leftOther * rightCount * rightOther
# count[mode] = 2 -- [a ?] a [? ?]
ans += leftCount * self._calc(num, leftOther, rightOther, left, right)
# count[mode] = 2 -- [? ?] a [a ?]
ans += rightCount * self._calc(num, rightOther, leftOther, right, left)
ans %= self.MOD
left[num] += 1
return ans
def _calc(
self,
a: int,
other1: int,
other2: int,
count1: dict[int, int],
count2: dict[int, int]
) -> int:
"""
Returns the count of subsequences that have `a` as the middle number, where
invalid subsequences are excluded.
"""
# [a ?] a [? ?]
res = (other1 * math.comb(other2, 2)) % self.MOD
for b, b1 in count1.items():
if b == a:
continue
b2 = count2[b]
# Exclude triples -- [a b] a [b b].
res = (res - b1 * math.comb(b2, 2)) % self.MOD
# Exclude doubles -- [a b] a [b ?].
res = (res - b1 * b2 * (other2 - b2)) % self.MOD
for b, b2 in count2.items():
if b == a:
continue
b1 = count1[b]
# Exclude doubles -- [a ?] a [b b].
res = (res - (other1 - b1) * math.comb(b2, 2)) % self.MOD
return (res + self.MOD) % self.MOD
// Accepted solution for LeetCode #3395: Subsequences with a Unique Middle Mode I
// Rust example auto-generated from java reference.
// Replace the signature and local types with the exact LeetCode harness for this problem.
impl Solution {
pub fn rust_example() {
// Port the logic from the reference block below.
}
}
// Reference (java):
// // Accepted solution for LeetCode #3395: Subsequences with a Unique Middle Mode I
// class Solution {
// public int subsequencesWithMiddleMode(int[] nums) {
// int n = nums.length;
// long ans = 0;
// Map<Integer, Integer> left = new HashMap<>();
// Map<Integer, Integer> right = new HashMap<>();
//
// for (int i = 0; i < 2; ++i)
// left.merge(nums[i], 1, Integer::sum);
//
// for (int i = 2; i < n; ++i)
// right.merge(nums[i], 1, Integer::sum);
//
// for (int i = 2; i < n - 2; ++i) {
// final int num = nums[i];
// if (right.merge(num, -1, Integer::sum) == 0)
// right.remove(num);
//
// final int leftCount = left.getOrDefault(num, 0);
// final int rightCount = right.getOrDefault(num, 0);
// final int leftOther = i - leftCount;
// final int rightOther = n - 1 - i - rightCount;
//
// // count[mode] = 5 -- [a a] a [a a]
// ans = (ans + nC2(leftCount) * nC2(rightCount)) % MOD;
//
// // count[mode] = 4 -- [a a] a [a ?]
// ans = (ans + nC2(leftCount) * rightCount % MOD * rightOther % MOD) % MOD;
//
// // count[mode] = 4 -- [a ?] a [a a]
// ans = (ans + leftCount * leftOther % MOD * nC2(rightCount) % MOD) % MOD;
//
// // count[mode] = 3 -- [a a] a [? ?]
// ans = (ans + nC2(leftCount) * nC2(rightOther) % MOD) % MOD;
//
// // count[mode] = 3 -- [? ?] a [a a]
// ans = (ans + nC2(leftOther) * nC2(rightCount) % MOD) % MOD;
//
// // count[mode] = 3 -- [a ?] a [a ?]
// ans = (ans + leftCount * leftOther % MOD * rightCount % MOD * rightOther % MOD) % MOD;
//
// // count[mode] = 2 -- [a ?] a [? ?]
// ans = (ans + leftCount * calc(num, leftOther, rightOther, left, right) % MOD) % MOD;
//
// // count[mode] = 2 -- [? ?] a [a ?]
// ans = (ans + rightCount * calc(num, rightOther, leftOther, right, left) % MOD) % MOD;
//
// // Update left map
// left.merge(num, 1, Integer::sum);
// }
//
// return (int) (ans % MOD);
// }
//
// private static final int MOD = 1_000_000_007;
//
// // Returns C(n, 2)
// private long nC2(long n) {
// return n * (n - 1) / 2 % MOD;
// }
//
// // Returns the count of subsequences that have 'a' as the middle number, where
// // invalid subsequences are excluded
// private long calc(int a, long other1, long other2, Map<Integer, Integer> count1,
// Map<Integer, Integer> count2) {
// // [a ?] a [? ?]
// long res = other1 * nC2(other2) % MOD;
//
// for (Map.Entry<Integer, Integer> entry : count1.entrySet()) {
// final int b = entry.getKey();
// final long b1 = entry.getValue();
// if (b == a)
// continue;
// final long b2 = count2.getOrDefault(b, 0);
// // Exclude triples -- [a b] a [b b]
// res = (res - b1 * nC2(b2) % MOD + MOD) % MOD;
// // Exclude doubles -- [a b] a [b ?]
// res = (res - b1 * b2 % MOD * (other2 - b2) % MOD + MOD) % MOD;
// }
//
// for (Map.Entry<Integer, Integer> entry : count2.entrySet()) {
// final int b = entry.getKey();
// final long b2 = entry.getValue();
// if (b == a)
// continue;
// final long b1 = count1.getOrDefault(b, 0);
// // Exclude doubles -- [a ?] a [b b]
// res = (res - (other1 - b1) * nC2(b2) % MOD + MOD) % MOD;
// }
//
// return res;
// }
// }
// Accepted solution for LeetCode #3395: Subsequences with a Unique Middle Mode I
// Auto-generated TypeScript example from java.
function exampleSolution(): void {
}
// Reference (java):
// // Accepted solution for LeetCode #3395: Subsequences with a Unique Middle Mode I
// class Solution {
// public int subsequencesWithMiddleMode(int[] nums) {
// int n = nums.length;
// long ans = 0;
// Map<Integer, Integer> left = new HashMap<>();
// Map<Integer, Integer> right = new HashMap<>();
//
// for (int i = 0; i < 2; ++i)
// left.merge(nums[i], 1, Integer::sum);
//
// for (int i = 2; i < n; ++i)
// right.merge(nums[i], 1, Integer::sum);
//
// for (int i = 2; i < n - 2; ++i) {
// final int num = nums[i];
// if (right.merge(num, -1, Integer::sum) == 0)
// right.remove(num);
//
// final int leftCount = left.getOrDefault(num, 0);
// final int rightCount = right.getOrDefault(num, 0);
// final int leftOther = i - leftCount;
// final int rightOther = n - 1 - i - rightCount;
//
// // count[mode] = 5 -- [a a] a [a a]
// ans = (ans + nC2(leftCount) * nC2(rightCount)) % MOD;
//
// // count[mode] = 4 -- [a a] a [a ?]
// ans = (ans + nC2(leftCount) * rightCount % MOD * rightOther % MOD) % MOD;
//
// // count[mode] = 4 -- [a ?] a [a a]
// ans = (ans + leftCount * leftOther % MOD * nC2(rightCount) % MOD) % MOD;
//
// // count[mode] = 3 -- [a a] a [? ?]
// ans = (ans + nC2(leftCount) * nC2(rightOther) % MOD) % MOD;
//
// // count[mode] = 3 -- [? ?] a [a a]
// ans = (ans + nC2(leftOther) * nC2(rightCount) % MOD) % MOD;
//
// // count[mode] = 3 -- [a ?] a [a ?]
// ans = (ans + leftCount * leftOther % MOD * rightCount % MOD * rightOther % MOD) % MOD;
//
// // count[mode] = 2 -- [a ?] a [? ?]
// ans = (ans + leftCount * calc(num, leftOther, rightOther, left, right) % MOD) % MOD;
//
// // count[mode] = 2 -- [? ?] a [a ?]
// ans = (ans + rightCount * calc(num, rightOther, leftOther, right, left) % MOD) % MOD;
//
// // Update left map
// left.merge(num, 1, Integer::sum);
// }
//
// return (int) (ans % MOD);
// }
//
// private static final int MOD = 1_000_000_007;
//
// // Returns C(n, 2)
// private long nC2(long n) {
// return n * (n - 1) / 2 % MOD;
// }
//
// // Returns the count of subsequences that have 'a' as the middle number, where
// // invalid subsequences are excluded
// private long calc(int a, long other1, long other2, Map<Integer, Integer> count1,
// Map<Integer, Integer> count2) {
// // [a ?] a [? ?]
// long res = other1 * nC2(other2) % MOD;
//
// for (Map.Entry<Integer, Integer> entry : count1.entrySet()) {
// final int b = entry.getKey();
// final long b1 = entry.getValue();
// if (b == a)
// continue;
// final long b2 = count2.getOrDefault(b, 0);
// // Exclude triples -- [a b] a [b b]
// res = (res - b1 * nC2(b2) % MOD + MOD) % MOD;
// // Exclude doubles -- [a b] a [b ?]
// res = (res - b1 * b2 % MOD * (other2 - b2) % MOD + MOD) % MOD;
// }
//
// for (Map.Entry<Integer, Integer> entry : count2.entrySet()) {
// final int b = entry.getKey();
// final long b2 = entry.getValue();
// if (b == a)
// continue;
// final long b1 = count1.getOrDefault(b, 0);
// // Exclude doubles -- [a ?] a [b b]
// res = (res - (other1 - b1) * nC2(b2) % MOD + MOD) % MOD;
// }
//
// return res;
// }
// }
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.