-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSuccessfulPairsOfSpellsAndPotions.java
More file actions
161 lines (129 loc) · 5.15 KB
/
SuccessfulPairsOfSpellsAndPotions.java
File metadata and controls
161 lines (129 loc) · 5.15 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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package Algorithms.BinarySearch;
import java.util.Arrays;
import java.util.HashMap;
/**
* @author Srinivas Vadige, srinivas.vadige@gmail.com
* @since 10 May 2025
*/
public class SuccessfulPairsOfSpellsAndPotions {
public static void main(String[] args) {
int[] spells = {15,39,38,35,33,25,31,12,40,27,29,16,22,24,7,36,29,34,24,9,11,35,21,3,33,10,9,27,35,17,14,3,35,35,39,23,35,14,31,7};
int[] potions = {25,19,30,37,14,30,38,22,38,38,26,33,34,23,40,28,15,29,36,39,39,37,32,38,8,17,39,20,4,39,39,7,30,35,29,23};
long success = 317;
System.out.println("successfulPairsMyApproach => " + Arrays.toString(successfulPairsMyApproach(spells, potions, success)));
System.out.println("successfulPairs => " + Arrays.toString(successfulPairs(spells, potions, success)));
System.out.println("successfulPairsSuggested => " + Arrays.toString(successfulPairsSuggested(spells, potions, success)));
}
/**
OBSERVATIONS:
-------------
pairs[i] = num of potions where it's product with spells[i] >= success
pairs.length = spells.length = n
APPROACHES:
----------
1. brute force ---> nm
2. potionsMap ---> nm
3. sorted potions[] ----> mlogm + nlogm
a. linear search
b. bs
*/
public static int[] successfulPairsMyApproach(int[] spells, int[] potions, long success) {
int n = spells.length, m = potions.length;
Arrays.sort(potions);
HashMap<Integer, Integer> memo = new HashMap<>();
int[] pairs = new int[n];
for (int i = 0; i < n; i++) {
int spell = spells[i];
if (memo.containsKey(spell)) {
pairs[i] = memo.get(spell);
continue;
}
// Quotient calculation
long quotient = (success / (long) spell); // Use long to avoid overflow
long remainder = (success % (long) spell); // Use long to avoid overflow
if (remainder > 0) quotient++;
int potionI = binarySearchMyApproach(potions, quotient, m); // Return m if not found
int numOfPotions = m - potionI;
pairs[i] = numOfPotions;
memo.put(spell, numOfPotions);
}
return pairs;
}
private static int binarySearchMyApproach(int[] potions, long target, int n) {
int l = 0, r = n - 1;
while (l <= r) {
int m = (l + r) / 2;
if (potions[m] == target) {
while (m > 0 && potions[m - 1] == target) m--; // Ensure the first occurrence
return m;
} else if (potions[m] < target) {
l = m + 1;
} else {
r = m - 1;
}
}
return l; // Return the first index where potions[index] >= target
}
/** */
public static int[] successfulPairs(int[] spells, int[] potions, long success) {
int n = spells.length, m = potions.length, pairs[] = new int[n];
Arrays.sort(potions);
for (int i = 0; i < n; i++) {
int spell=spells[i], l=0, r=m-1;
while (l<=r) {
int mid = l+(r-l)/2;
long product = (long) spell * potions[mid];
if (product >= success) {
r = mid - 1;
} else {
l = mid + 1;
}
}
pairs[i] = m - l; // how many on the right side of target potion (including target if exists)
}
return pairs;
}
public static int[] successfulPairs2(int[] spells, int[] potions, long success) {
int n = spells.length, m = potions.length, pairs[] = new int[n];
Arrays.sort(potions);
for (int i = 0; i < n; i++) {
int spell=spells[i], l=0, r=m-1, idx=m;
while (l<=r) {
int mid = l+(r-l)/2;
long product = (long) spell * potions[mid];
if (product >= success) {
r = mid - 1;
idx = mid;
} else {
l = mid + 1;
}
}
pairs[i] = m - idx;
}
return pairs;
}
public static int[] successfulPairsSuggested(int[] spells, int[] potions, long success) {
int n = spells.length, m = potions.length;
Arrays.sort(potions);
int[] pairs = new int[n];
for (int i = 0; i < n; i++) {
long spell = spells[i];
long required = (success + spell - 1) / spell; // Ceiling of success / spell
int potionIndex = binarySearch(potions, required, m); // Find the first potion >= required
pairs[i] = m - potionIndex; // Count of successful pairs
}
return pairs;
}
private static int binarySearch(int[] potions, long required, int n) {
int left = 0, right = n - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (potions[mid] >= required) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return left; // First index where potions[index] >= required
}
}