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.
Build confidence with an intuition-first walkthrough focused on array fundamentals.
Given an array of integers arr, a lucky integer is an integer that has a frequency in the array equal to its value.
Return the largest lucky integer in the array. If there is no lucky integer return -1.
Example 1:
Input: arr = [2,2,3,4] Output: 2 Explanation: The only lucky number in the array is 2 because frequency[2] == 2.
Example 2:
Input: arr = [1,2,2,3,3,3] Output: 3 Explanation: 1, 2 and 3 are all lucky numbers, return the largest of them.
Example 3:
Input: arr = [2,2,2,3,3] Output: -1 Explanation: There are no lucky numbers in the array.
Constraints:
1 <= arr.length <= 5001 <= arr[i] <= 500Problem summary: Given an array of integers arr, a lucky integer is an integer that has a frequency in the array equal to its value. Return the largest lucky integer in the array. If there is no lucky integer return -1.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Hash Map
[2,2,3,4]
[1,2,2,3,3,3]
[2,2,2,3,3]
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #1394: Find Lucky Integer in an Array
class Solution {
public int findLucky(int[] arr) {
int[] cnt = new int[501];
for (int x : arr) {
++cnt[x];
}
for (int x = cnt.length - 1; x > 0; --x) {
if (x == cnt[x]) {
return x;
}
}
return -1;
}
}
// Accepted solution for LeetCode #1394: Find Lucky Integer in an Array
func findLucky(arr []int) int {
cnt := [501]int{}
for _, x := range arr {
cnt[x]++
}
for x := len(cnt) - 1; x > 0; x-- {
if x == cnt[x] {
return x
}
}
return -1
}
# Accepted solution for LeetCode #1394: Find Lucky Integer in an Array
class Solution:
def findLucky(self, arr: List[int]) -> int:
cnt = Counter(arr)
return max((x for x, v in cnt.items() if x == v), default=-1)
// Accepted solution for LeetCode #1394: Find Lucky Integer in an Array
use std::collections::HashMap;
impl Solution {
pub fn find_lucky(arr: Vec<i32>) -> i32 {
let mut cnt = HashMap::new();
arr.iter().for_each(|&x| *cnt.entry(x).or_insert(0) += 1);
cnt.iter()
.filter(|(&x, &v)| x == v)
.map(|(&x, _)| x)
.max()
.unwrap_or(-1)
}
}
// Accepted solution for LeetCode #1394: Find Lucky Integer in an Array
function findLucky(arr: number[]): number {
const cnt: number[] = Array(501).fill(0);
for (const x of arr) {
++cnt[x];
}
for (let x = cnt.length - 1; x; --x) {
if (x === cnt[x]) {
return x;
}
}
return -1;
}
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.