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.
You are given a non-negative integer array nums and an integer k.
You must select a subarray of nums such that the difference between its maximum and minimum elements is at most k. The value of this subarray is the bitwise XOR of all elements in the subarray.
Return an integer denoting the maximum possible value of the selected subarray.
Example 1:
Input: nums = [5,4,5,6], k = 2
Output: 7
Explanation:
[5, 4, 5, 6].6 - 4 = 2 <= k.4 XOR 5 XOR 6 = 7.Example 2:
Input: nums = [5,4,5,6], k = 1
Output: 6
Explanation:
[5, 4, 5, 6].6 - 6 = 0 <= k.Constraints:
1 <= nums.length <= 4 * 1040 <= nums[i] < 2150 <= k < 215Problem summary: You are given a non-negative integer array nums and an integer k. You must select a subarray of nums such that the difference between its maximum and minimum elements is at most k. The value of this subarray is the bitwise XOR of all elements in the subarray. Return an integer denoting the maximum possible value of the selected subarray.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: General problem-solving
[5,4,5,6] 2
[5,4,5,6] 1
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3845: Maximum Subarray XOR with Bounded Range
// Auto-generated Java example from go.
class Solution {
public void exampleSolution() {
}
}
// Reference (go):
// // Accepted solution for LeetCode #3845: Maximum Subarray XOR with Bounded Range
// package main
//
// import "math/bits"
//
// // https://space.bilibili.com/206214
// const width = 15 // nums[i] 二进制长度的最大值
//
// type node struct {
// son [2]*node
// leaf int // 子树叶子个数
// }
//
// type trie struct {
// root *node
// }
//
// func newTrie() *trie {
// return &trie{&node{}}
// }
//
// func (t *trie) put(val int) {
// cur := t.root
// for i := width - 1; i >= 0; i-- {
// bit := val >> i & 1
// if cur.son[bit] == nil {
// cur.son[bit] = &node{}
// }
// cur = cur.son[bit]
// cur.leaf++
// }
// }
//
// func (t *trie) del(val int) {
// cur := t.root
// for i := width - 1; i >= 0; i-- {
// cur = cur.son[val>>i&1]
// cur.leaf-- // 如果减成 0 了,说明子树是空的,可以理解成 cur == nil
// }
// }
//
// func (t *trie) maxXor(val int) (ans int) {
// cur := t.root
// for i := width - 1; i >= 0; i-- {
// bit := val >> i & 1
// if cur.son[bit^1] != nil && cur.son[bit^1].leaf > 0 {
// ans |= 1 << i
// bit ^= 1
// }
// cur = cur.son[bit]
// }
// return
// }
//
// func maxXor1(nums []int, k int) (ans int) {
// sum := make([]int, len(nums)+1)
// for i, x := range nums {
// sum[i+1] = sum[i] ^ x
// }
//
// t := newTrie()
// var minQ, maxQ []int
// left := 0
// for right, x := range nums {
// // 1. 入
// t.put(sum[right])
//
// for len(minQ) > 0 && x <= nums[minQ[len(minQ)-1]] {
// minQ = minQ[:len(minQ)-1]
// }
// minQ = append(minQ, right)
//
// for len(maxQ) > 0 && x >= nums[maxQ[len(maxQ)-1]] {
// maxQ = maxQ[:len(maxQ)-1]
// }
// maxQ = append(maxQ, right)
//
// // 2. 出
// for nums[maxQ[0]]-nums[minQ[0]] > k {
// t.del(sum[left])
// left++
// if minQ[0] < left {
// minQ = minQ[1:]
// }
// if maxQ[0] < left {
// maxQ = maxQ[1:]
// }
// }
//
// // 3. 更新答案
// ans = max(ans, t.maxXor(sum[right+1]))
// }
// return
// }
//
// func maxXor(nums []int, k int) (ans int) {
// // 预处理:当窗口右端点在 right 时,窗口左端点在 lefts[right]
// // 顺带算出前缀异或和、nums 的最大值
// n := len(nums)
// lefts := make([]int, n)
// sum := make([]int, len(nums)+1)
// mx := 0
// var minQ, maxQ []int
// left := 0
// for right, x := range nums {
// sum[right+1] = sum[right] ^ x
// mx = max(mx, x)
//
// // 1. 入
// for len(minQ) > 0 && x <= nums[minQ[len(minQ)-1]] {
// minQ = minQ[:len(minQ)-1]
// }
// minQ = append(minQ, right)
//
// for len(maxQ) > 0 && x >= nums[maxQ[len(maxQ)-1]] {
// maxQ = maxQ[:len(maxQ)-1]
// }
// maxQ = append(maxQ, right)
//
// // 2. 出
// for nums[maxQ[0]]-nums[minQ[0]] > k {
// left++
// if minQ[0] < left {
// minQ = minQ[1:]
// }
// if maxQ[0] < left {
// maxQ = maxQ[1:]
// }
// }
//
// // 3. 记录此时的 left
// lefts[right] = left
// }
//
// // 试填法
// width := bits.Len(uint(mx))
// last := make([]int, 1<<width)
// for i := width - 1; i >= 0; i-- {
// for j := range 1 << (width - i) {
// last[j] = -1
// }
// last[0] = 0 // sum[0] = 0 的位置是 0
// ans <<= 1
// newAns := ans | 1
// for right, l := range lefts {
// s := sum[right+1] >> i // 去掉低位,只看高位
// if last[newAns^s] >= l { // newAns^s 存在,且在窗口内
// ans = newAns // 最终答案第 i 位填 1
// break
// }
// last[s] = right + 1
// }
// }
//
// return
// }
// Accepted solution for LeetCode #3845: Maximum Subarray XOR with Bounded Range
package main
import "math/bits"
// https://space.bilibili.com/206214
const width = 15 // nums[i] 二进制长度的最大值
type node struct {
son [2]*node
leaf int // 子树叶子个数
}
type trie struct {
root *node
}
func newTrie() *trie {
return &trie{&node{}}
}
func (t *trie) put(val int) {
cur := t.root
for i := width - 1; i >= 0; i-- {
bit := val >> i & 1
if cur.son[bit] == nil {
cur.son[bit] = &node{}
}
cur = cur.son[bit]
cur.leaf++
}
}
func (t *trie) del(val int) {
cur := t.root
for i := width - 1; i >= 0; i-- {
cur = cur.son[val>>i&1]
cur.leaf-- // 如果减成 0 了,说明子树是空的,可以理解成 cur == nil
}
}
func (t *trie) maxXor(val int) (ans int) {
cur := t.root
for i := width - 1; i >= 0; i-- {
bit := val >> i & 1
if cur.son[bit^1] != nil && cur.son[bit^1].leaf > 0 {
ans |= 1 << i
bit ^= 1
}
cur = cur.son[bit]
}
return
}
func maxXor1(nums []int, k int) (ans int) {
sum := make([]int, len(nums)+1)
for i, x := range nums {
sum[i+1] = sum[i] ^ x
}
t := newTrie()
var minQ, maxQ []int
left := 0
for right, x := range nums {
// 1. 入
t.put(sum[right])
for len(minQ) > 0 && x <= nums[minQ[len(minQ)-1]] {
minQ = minQ[:len(minQ)-1]
}
minQ = append(minQ, right)
for len(maxQ) > 0 && x >= nums[maxQ[len(maxQ)-1]] {
maxQ = maxQ[:len(maxQ)-1]
}
maxQ = append(maxQ, right)
// 2. 出
for nums[maxQ[0]]-nums[minQ[0]] > k {
t.del(sum[left])
left++
if minQ[0] < left {
minQ = minQ[1:]
}
if maxQ[0] < left {
maxQ = maxQ[1:]
}
}
// 3. 更新答案
ans = max(ans, t.maxXor(sum[right+1]))
}
return
}
func maxXor(nums []int, k int) (ans int) {
// 预处理:当窗口右端点在 right 时,窗口左端点在 lefts[right]
// 顺带算出前缀异或和、nums 的最大值
n := len(nums)
lefts := make([]int, n)
sum := make([]int, len(nums)+1)
mx := 0
var minQ, maxQ []int
left := 0
for right, x := range nums {
sum[right+1] = sum[right] ^ x
mx = max(mx, x)
// 1. 入
for len(minQ) > 0 && x <= nums[minQ[len(minQ)-1]] {
minQ = minQ[:len(minQ)-1]
}
minQ = append(minQ, right)
for len(maxQ) > 0 && x >= nums[maxQ[len(maxQ)-1]] {
maxQ = maxQ[:len(maxQ)-1]
}
maxQ = append(maxQ, right)
// 2. 出
for nums[maxQ[0]]-nums[minQ[0]] > k {
left++
if minQ[0] < left {
minQ = minQ[1:]
}
if maxQ[0] < left {
maxQ = maxQ[1:]
}
}
// 3. 记录此时的 left
lefts[right] = left
}
// 试填法
width := bits.Len(uint(mx))
last := make([]int, 1<<width)
for i := width - 1; i >= 0; i-- {
for j := range 1 << (width - i) {
last[j] = -1
}
last[0] = 0 // sum[0] = 0 的位置是 0
ans <<= 1
newAns := ans | 1
for right, l := range lefts {
s := sum[right+1] >> i // 去掉低位,只看高位
if last[newAns^s] >= l { // newAns^s 存在,且在窗口内
ans = newAns // 最终答案第 i 位填 1
break
}
last[s] = right + 1
}
}
return
}
# Accepted solution for LeetCode #3845: Maximum Subarray XOR with Bounded Range
# Time: O(nlogr), r = max(max(nums), 1)
# Space: O(n)
import collections
# two pointers, mono deque, bitmasks, prefix sum, hash table
class Solution(object):
def maxXor(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
lookup = [-1]*len(nums)
max_dq = collections.deque()
min_dq = collections.deque()
left = 0
for right in xrange(len(nums)):
while max_dq and nums[max_dq[-1]] <= nums[right]:
max_dq.pop()
max_dq.append(right)
while min_dq and nums[min_dq[-1]] >= nums[right]:
min_dq.pop()
min_dq.append(right)
while nums[max_dq[0]]-nums[min_dq[0]] > k:
if max_dq and max_dq[0] == left:
max_dq.popleft()
if min_dq and min_dq[0] == left:
min_dq.popleft()
left += 1
lookup[right] = left
result = 0
mx = max(max(nums), 1)
for i in reversed(xrange(mx.bit_length())):
lookup2 = collections.defaultdict(int)
lookup2[0] = prefix = 0
for right in xrange(len(nums)):
prefix ^= nums[right]>>i
if ((result>>i)|1)^prefix in lookup2 and lookup2[((result>>i)|1)^prefix] >= lookup[right]:
result |= 1<<i
break
lookup2[prefix] = right+1
return result
# Time: O(nlogr), r = max(max(nums), 1)
# Space: O(n + t)
import collections
# two pointers, mono deque, bitmasks, prefix sum, trie
class Solution2(object):
def maxXor(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
class Trie(object):
def __init__(self, bit_length):
self.__lefts = [-1]*(1+(1+len(nums))*bit_length) # preallocate to speed up performance
self.__rights = [-1]*(1+(1+len(nums))*bit_length)
self.__cnts = [0]*(1+(1+len(nums))*bit_length)
self.__i = 0
self.__new_node()
self.__bit_length = bit_length
def __new_node(self):
self.__i += 1
return self.__i-1
def add(self, num, diff):
curr = 0
for i in reversed(xrange(self.__bit_length)):
x = (num>>i)&1
if x == 0:
if self.__lefts[curr] == -1:
self.__lefts[curr] = self.__new_node()
curr = self.__lefts[curr]
else:
if self.__rights[curr] == -1:
self.__rights[curr] = self.__new_node()
curr = self.__rights[curr]
self.__cnts[curr] += diff
def query(self, prefix):
result = curr = 0
for i in reversed(xrange(self.__bit_length)):
x = (prefix>>i)&1
l, r = (self.__lefts, self.__rights) if x^1 else (self.__rights, self.__lefts)
if r[curr] != -1 and self.__cnts[r[curr]]:
result |= 1<<i
curr = r[curr]
else:
curr = l[curr]
return result
result = 0
prefix = [0]*(len(nums)+1)
for i in xrange(len(nums)):
prefix[i+1] = prefix[i]^nums[i]
mx = max(max(nums), 1)
trie = Trie(mx.bit_length())
trie.add(prefix[0], +1)
max_dq = collections.deque()
min_dq = collections.deque()
left = 0
for right in xrange(len(nums)):
while max_dq and nums[max_dq[-1]] <= nums[right]:
max_dq.pop()
max_dq.append(right)
while min_dq and nums[min_dq[-1]] >= nums[right]:
min_dq.pop()
min_dq.append(right)
while nums[max_dq[0]]-nums[min_dq[0]] > k:
trie.add(prefix[left], -1)
if max_dq and max_dq[0] == left:
max_dq.popleft()
if min_dq and min_dq[0] == left:
min_dq.popleft()
left += 1
result = max(result, trie.query(prefix[right+1]))
trie.add(prefix[right+1], +1)
return result
# Time: O(nlogr), r = max(max(nums), 1)
# Space: O(n + t)
import collections
# two pointers, mono deque, bitmasks, prefix sum, trie
class Solution3(object):
def maxXor(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
class Trie(object):
def __init__(self, bit_length):
self.__nodes = []
self.__cnts = []
self.__new_node()
self.__bit_length = bit_length
def __new_node(self):
self.__nodes.append([-1]*2)
self.__cnts.append(0)
return len(self.__nodes)-1
def add(self, num, diff):
curr = 0
for i in reversed(xrange(self.__bit_length)):
x = (num>>i)&1
if self.__nodes[curr][x] == -1:
self.__nodes[curr][x] = self.__new_node()
curr = self.__nodes[curr][x]
self.__cnts[curr] += diff
def query(self, prefix):
result = curr = 0
for i in reversed(xrange(self.__bit_length)):
x = (prefix>>i)&1
if self.__nodes[curr][x^1] != -1 and self.__cnts[self.__nodes[curr][x^1]]:
result |= 1<<i
curr = self.__nodes[curr][x^1]
else:
curr = self.__nodes[curr][x]
return result
result = 0
prefix = [0]*(len(nums)+1)
for i in xrange(len(nums)):
prefix[i+1] = prefix[i]^nums[i]
mx = max(max(nums), 1)
trie = Trie(mx.bit_length())
trie.add(prefix[0], +1)
max_dq = collections.deque()
min_dq = collections.deque()
left = 0
for right in xrange(len(nums)):
while max_dq and nums[max_dq[-1]] <= nums[right]:
max_dq.pop()
max_dq.append(right)
while min_dq and nums[min_dq[-1]] >= nums[right]:
min_dq.pop()
min_dq.append(right)
while nums[max_dq[0]]-nums[min_dq[0]] > k:
trie.add(prefix[left], -1)
if max_dq and max_dq[0] == left:
max_dq.popleft()
if min_dq and min_dq[0] == left:
min_dq.popleft()
left += 1
result = max(result, trie.query(prefix[right+1]))
trie.add(prefix[right+1], +1)
return result
// Accepted solution for LeetCode #3845: Maximum Subarray XOR with Bounded Range
// Rust example auto-generated from go 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 (go):
// // Accepted solution for LeetCode #3845: Maximum Subarray XOR with Bounded Range
// package main
//
// import "math/bits"
//
// // https://space.bilibili.com/206214
// const width = 15 // nums[i] 二进制长度的最大值
//
// type node struct {
// son [2]*node
// leaf int // 子树叶子个数
// }
//
// type trie struct {
// root *node
// }
//
// func newTrie() *trie {
// return &trie{&node{}}
// }
//
// func (t *trie) put(val int) {
// cur := t.root
// for i := width - 1; i >= 0; i-- {
// bit := val >> i & 1
// if cur.son[bit] == nil {
// cur.son[bit] = &node{}
// }
// cur = cur.son[bit]
// cur.leaf++
// }
// }
//
// func (t *trie) del(val int) {
// cur := t.root
// for i := width - 1; i >= 0; i-- {
// cur = cur.son[val>>i&1]
// cur.leaf-- // 如果减成 0 了,说明子树是空的,可以理解成 cur == nil
// }
// }
//
// func (t *trie) maxXor(val int) (ans int) {
// cur := t.root
// for i := width - 1; i >= 0; i-- {
// bit := val >> i & 1
// if cur.son[bit^1] != nil && cur.son[bit^1].leaf > 0 {
// ans |= 1 << i
// bit ^= 1
// }
// cur = cur.son[bit]
// }
// return
// }
//
// func maxXor1(nums []int, k int) (ans int) {
// sum := make([]int, len(nums)+1)
// for i, x := range nums {
// sum[i+1] = sum[i] ^ x
// }
//
// t := newTrie()
// var minQ, maxQ []int
// left := 0
// for right, x := range nums {
// // 1. 入
// t.put(sum[right])
//
// for len(minQ) > 0 && x <= nums[minQ[len(minQ)-1]] {
// minQ = minQ[:len(minQ)-1]
// }
// minQ = append(minQ, right)
//
// for len(maxQ) > 0 && x >= nums[maxQ[len(maxQ)-1]] {
// maxQ = maxQ[:len(maxQ)-1]
// }
// maxQ = append(maxQ, right)
//
// // 2. 出
// for nums[maxQ[0]]-nums[minQ[0]] > k {
// t.del(sum[left])
// left++
// if minQ[0] < left {
// minQ = minQ[1:]
// }
// if maxQ[0] < left {
// maxQ = maxQ[1:]
// }
// }
//
// // 3. 更新答案
// ans = max(ans, t.maxXor(sum[right+1]))
// }
// return
// }
//
// func maxXor(nums []int, k int) (ans int) {
// // 预处理:当窗口右端点在 right 时,窗口左端点在 lefts[right]
// // 顺带算出前缀异或和、nums 的最大值
// n := len(nums)
// lefts := make([]int, n)
// sum := make([]int, len(nums)+1)
// mx := 0
// var minQ, maxQ []int
// left := 0
// for right, x := range nums {
// sum[right+1] = sum[right] ^ x
// mx = max(mx, x)
//
// // 1. 入
// for len(minQ) > 0 && x <= nums[minQ[len(minQ)-1]] {
// minQ = minQ[:len(minQ)-1]
// }
// minQ = append(minQ, right)
//
// for len(maxQ) > 0 && x >= nums[maxQ[len(maxQ)-1]] {
// maxQ = maxQ[:len(maxQ)-1]
// }
// maxQ = append(maxQ, right)
//
// // 2. 出
// for nums[maxQ[0]]-nums[minQ[0]] > k {
// left++
// if minQ[0] < left {
// minQ = minQ[1:]
// }
// if maxQ[0] < left {
// maxQ = maxQ[1:]
// }
// }
//
// // 3. 记录此时的 left
// lefts[right] = left
// }
//
// // 试填法
// width := bits.Len(uint(mx))
// last := make([]int, 1<<width)
// for i := width - 1; i >= 0; i-- {
// for j := range 1 << (width - i) {
// last[j] = -1
// }
// last[0] = 0 // sum[0] = 0 的位置是 0
// ans <<= 1
// newAns := ans | 1
// for right, l := range lefts {
// s := sum[right+1] >> i // 去掉低位,只看高位
// if last[newAns^s] >= l { // newAns^s 存在,且在窗口内
// ans = newAns // 最终答案第 i 位填 1
// break
// }
// last[s] = right + 1
// }
// }
//
// return
// }
// Accepted solution for LeetCode #3845: Maximum Subarray XOR with Bounded Range
// Auto-generated TypeScript example from go.
function exampleSolution(): void {
}
// Reference (go):
// // Accepted solution for LeetCode #3845: Maximum Subarray XOR with Bounded Range
// package main
//
// import "math/bits"
//
// // https://space.bilibili.com/206214
// const width = 15 // nums[i] 二进制长度的最大值
//
// type node struct {
// son [2]*node
// leaf int // 子树叶子个数
// }
//
// type trie struct {
// root *node
// }
//
// func newTrie() *trie {
// return &trie{&node{}}
// }
//
// func (t *trie) put(val int) {
// cur := t.root
// for i := width - 1; i >= 0; i-- {
// bit := val >> i & 1
// if cur.son[bit] == nil {
// cur.son[bit] = &node{}
// }
// cur = cur.son[bit]
// cur.leaf++
// }
// }
//
// func (t *trie) del(val int) {
// cur := t.root
// for i := width - 1; i >= 0; i-- {
// cur = cur.son[val>>i&1]
// cur.leaf-- // 如果减成 0 了,说明子树是空的,可以理解成 cur == nil
// }
// }
//
// func (t *trie) maxXor(val int) (ans int) {
// cur := t.root
// for i := width - 1; i >= 0; i-- {
// bit := val >> i & 1
// if cur.son[bit^1] != nil && cur.son[bit^1].leaf > 0 {
// ans |= 1 << i
// bit ^= 1
// }
// cur = cur.son[bit]
// }
// return
// }
//
// func maxXor1(nums []int, k int) (ans int) {
// sum := make([]int, len(nums)+1)
// for i, x := range nums {
// sum[i+1] = sum[i] ^ x
// }
//
// t := newTrie()
// var minQ, maxQ []int
// left := 0
// for right, x := range nums {
// // 1. 入
// t.put(sum[right])
//
// for len(minQ) > 0 && x <= nums[minQ[len(minQ)-1]] {
// minQ = minQ[:len(minQ)-1]
// }
// minQ = append(minQ, right)
//
// for len(maxQ) > 0 && x >= nums[maxQ[len(maxQ)-1]] {
// maxQ = maxQ[:len(maxQ)-1]
// }
// maxQ = append(maxQ, right)
//
// // 2. 出
// for nums[maxQ[0]]-nums[minQ[0]] > k {
// t.del(sum[left])
// left++
// if minQ[0] < left {
// minQ = minQ[1:]
// }
// if maxQ[0] < left {
// maxQ = maxQ[1:]
// }
// }
//
// // 3. 更新答案
// ans = max(ans, t.maxXor(sum[right+1]))
// }
// return
// }
//
// func maxXor(nums []int, k int) (ans int) {
// // 预处理:当窗口右端点在 right 时,窗口左端点在 lefts[right]
// // 顺带算出前缀异或和、nums 的最大值
// n := len(nums)
// lefts := make([]int, n)
// sum := make([]int, len(nums)+1)
// mx := 0
// var minQ, maxQ []int
// left := 0
// for right, x := range nums {
// sum[right+1] = sum[right] ^ x
// mx = max(mx, x)
//
// // 1. 入
// for len(minQ) > 0 && x <= nums[minQ[len(minQ)-1]] {
// minQ = minQ[:len(minQ)-1]
// }
// minQ = append(minQ, right)
//
// for len(maxQ) > 0 && x >= nums[maxQ[len(maxQ)-1]] {
// maxQ = maxQ[:len(maxQ)-1]
// }
// maxQ = append(maxQ, right)
//
// // 2. 出
// for nums[maxQ[0]]-nums[minQ[0]] > k {
// left++
// if minQ[0] < left {
// minQ = minQ[1:]
// }
// if maxQ[0] < left {
// maxQ = maxQ[1:]
// }
// }
//
// // 3. 记录此时的 left
// lefts[right] = left
// }
//
// // 试填法
// width := bits.Len(uint(mx))
// last := make([]int, 1<<width)
// for i := width - 1; i >= 0; i-- {
// for j := range 1 << (width - i) {
// last[j] = -1
// }
// last[0] = 0 // sum[0] = 0 的位置是 0
// ans <<= 1
// newAns := ans | 1
// for right, l := range lefts {
// s := sum[right+1] >> i // 去掉低位,只看高位
// if last[newAns^s] >= l { // newAns^s 存在,且在窗口内
// ans = newAns // 最终答案第 i 位填 1
// break
// }
// last[s] = right + 1
// }
// }
//
// return
// }
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.