-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathFindLuckyIntegerinanArray1394.java
More file actions
95 lines (88 loc) · 3.66 KB
/
Copy pathFindLuckyIntegerinanArray1394.java
File metadata and controls
95 lines (88 loc) · 3.66 KB
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
* Problem: 1394. Find Lucky Integer in an Array
*
* Problem Statement:
* A lucky integer is an integer that has a frequency in the array equal to its value.
* Given an array of integers, return the largest lucky integer in the array.
* If there is no lucky integer, return -1.
*
* Intuition:
* The core requirement is to map values to their occurrences. Once we have the frequency
* of each number, we simply compare the number itself to its count. To find the "largest"
* lucky integer, we can either track a maximum during iteration or iterate through
* possible values in descending order.
*
* Approach:
* 1. Method 1 (HashMap): Use a HashMap to store the frequency of each integer.
* Iterate through the map's keys and update a result variable if key == frequency.
* 2. Method 2 (Frequency Array): Since the problem constraints (usually 1-500)
* allow it, use a fixed-size array where the index represents the number and
* the value at that index represents the count. Iterate backwards to find the
* first (largest) lucky integer.
*
* Time Complexity: O(N) where N is the length of the input array. We traverse the
* array once to count frequencies and then traverse the unique elements.
* Space Complexity: O(N) for the HashMap approach, or O(1) for the frequency array
* approach (since the array size is fixed at 501 regardless of input size N).
*
* Edge Cases:
* - No lucky integer exists: Should return -1.
* - Multiple lucky integers: Should return the largest one.
* - Array contains only one element: Check if that element is 1.
*
* Dry Run:
* Input: arr = [2, 2, 3, 3, 3]
* 1. Count frequencies: {2: 2, 3: 3}
* 2. Check 2: frequency is 2. 2 == 2, so lucky. res = 2.
* 3. Check 3: frequency is 3. 3 == 3, so lucky. res = max(2, 3) = 3.
* Output: 3
*
* Correctness Check:
* The solution is correct. Method 1 handles any integer range, while Method 2
* is optimized for the specific constraint that values are between 1 and 500.
*/
import java.util.HashMap;
public class FindLuckyIntegerinanArray1394 {
/**
* Approach 1: Using a HashMap.
* This is a general-purpose solution that works regardless of the range of values in arr.
*/
public int findLucky(int[] arr) {
int res = -1;
HashMap<Integer, Integer> map = new HashMap<>();
// Step 1: Build the frequency map.
// getOrDefault handles the case where the key is not yet in the map.
for (int x : arr) {
map.put(x, map.getOrDefault(x, 0) + 1);
}
// Step 2: Iterate through unique numbers to find the largest lucky integer.
for (int x : map.keySet()) {
// A lucky integer's value must equal its frequency.
if (map.get(x) == x) {
res = Math.max(res, x);
}
}
return res;
}
/**
* Approach 2: Using a Frequency Array (Counting Sort style).
* This is more space-efficient and faster if the range of values is small and known.
*/
public int findLucky2(int[] arr) {
// Constraint: 1 <= arr[i] <= 500. We use size 501 to include index 500.
int[] count = new int[501];
// Step 1: Increment the count at the index corresponding to the value.
for (int x : arr) {
count[x]++;
}
// Step 2: Iterate backwards from the maximum possible value.
// This ensures the first lucky integer we find is the largest one.
for (int i = 500; i > 0; i--) {
if (count[i] == i) {
return i;
}
}
// If no lucky integer is found after checking all indices.
return -1;
}
}