Skip to content

Commit e715121

Browse files
authored
Added tasks 2501, 2502
1 parent 99eacd5 commit e715121

File tree

7 files changed

+272
-0
lines changed

7 files changed

+272
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1848,6 +1848,8 @@ implementation 'com.github.javadev:leetcode-in-java:1.19'
18481848

18491849
| # | Title | Difficulty | Tag | Time, ms | Time, %
18501850
|------|----------------|-------------|-------------|----------|---------
1851+
| 2502 |[Design Memory Allocator](src/main/java/g2501_2600/s2502_design_memory_allocator/Allocator.java)| Medium | Array, Hash_Table, Design, Simulation | 9 | 100.00
1852+
| 2501 |[Longest Square Streak in an Array](src/main/java/g2501_2600/s2501_longest_square_streak_in_an_array/Solution.java)| Medium | Array, Hash_Table, Dynamic_Programming, Sorting, Binary_Search | 4 | 99.73
18511853
| 2500 |[Delete Greatest Value in Each Row](src.save/main/java/g2401_2500/s2500_delete_greatest_value_in_each_row/Solution.java)| Easy | Array, Sorting, Matrix | 3 | 98.16
18521854
| 2499 |[Minimum Total Cost to Make Arrays Unequal](src.save/main/java/g2401_2500/s2499_minimum_total_cost_to_make_arrays_unequal/Solution.java)| Hard | Array, Hash_Table, Greedy, Counting | 3 | 100.00
18531855
| 2498 |[Frog Jump II](src.save/main/java/g2401_2500/s2498_frog_jump_ii/Solution.java)| Medium | Array, Greedy, Binary_Search | 1 | 100.00
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package g2501_2600.s2501_longest_square_streak_in_an_array;
2+
3+
// #Medium #Array #Hash_Table #Dynamic_Programming #Sorting #Binary_Search
4+
// #2023_03_19_Time_4_ms_(99.73%)_Space_56_MB_(96.80%)
5+
6+
public class Solution {
7+
public int longestSquareStreak(int[] nums) {
8+
int result = -1;
9+
final int max = 100000;
10+
boolean[] isExisted = new boolean[max + 1];
11+
boolean[] isVisited = new boolean[max + 1];
12+
for (int num : nums) {
13+
isExisted[num] = true;
14+
}
15+
for (int i = 2; i * i <= max; i++) {
16+
if (!isExisted[i] || isVisited[i]) {
17+
continue;
18+
}
19+
isVisited[i] = true;
20+
int length = 1;
21+
int j = i * i;
22+
while (j >= 0 && j <= max && isExisted[j]) {
23+
isVisited[j] = true;
24+
length++;
25+
j = j * j;
26+
}
27+
if (length > 1) {
28+
result = Math.max(result, length);
29+
}
30+
}
31+
return result;
32+
}
33+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2501\. Longest Square Streak in an Array
2+
3+
Medium
4+
5+
You are given an integer array `nums`. A subsequence of `nums` is called a **square streak** if:
6+
7+
* The length of the subsequence is at least `2`, and
8+
* **after** sorting the subsequence, each element (except the first element) is the **square** of the previous number.
9+
10+
Return _the length of the **longest square streak** in_ `nums`_, or return_ `-1` _if there is no **square streak**._
11+
12+
A **subsequence** is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements.
13+
14+
**Example 1:**
15+
16+
**Input:** nums = [4,3,6,16,8,2]
17+
18+
**Output:** 3
19+
20+
**Explanation:** Choose the subsequence [4,16,2]. After sorting it, it becomes [2,4,16].
21+
22+
- 4 = 2 \* 2.
23+
24+
- 16 = 4 \* 4.
25+
26+
Therefore, [4,16,2] is a square streak.
27+
28+
It can be shown that every subsequence of length 4 is not a square streak.
29+
30+
**Example 2:**
31+
32+
**Input:** nums = [2,3,5,6,7]
33+
34+
**Output:** -1
35+
36+
**Explanation:** There is no square streak in nums so return -1.
37+
38+
**Constraints:**
39+
40+
* <code>2 <= nums.length <= 10<sup>5</sup></code>
41+
* <code>2 <= nums[i] <= 10<sup>5</sup></code>
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package g2501_2600.s2502_design_memory_allocator;
2+
3+
// #Medium #Array #Hash_Table #Design #Simulation
4+
// #2023_03_19_Time_9_ms_(100.00%)_Space_43_MB_(66.82%)
5+
6+
public class Allocator {
7+
Node root;
8+
9+
public Allocator(int n) {
10+
root = new Node(0, n, -1);
11+
}
12+
13+
public int allocate(int size, int mID) {
14+
Node cur = root;
15+
while (cur != null && (cur.size < size || cur.id != -1)) {
16+
cur = cur.next;
17+
}
18+
// unable to allocate
19+
if (cur == null) {
20+
return -1;
21+
}
22+
if (cur.size == size) {
23+
cur.id = mID;
24+
return cur.ind;
25+
} else {
26+
Node n = new Node(cur.ind + size, cur.size - size, -1);
27+
n.next = cur.next;
28+
cur.next = n;
29+
cur.size = size;
30+
cur.id = mID;
31+
return cur.ind;
32+
}
33+
}
34+
35+
public int free(int mID) {
36+
return collapse(root, mID);
37+
}
38+
39+
public int collapse(Node cur, int id) {
40+
// base case
41+
if (cur == null) {
42+
return 0;
43+
}
44+
// include size if matching id
45+
int res = cur.id == id ? cur.size : 0;
46+
// recurse on child
47+
res += collapse(cur.next, id);
48+
// unallocate
49+
if (cur.id == id) {
50+
cur.id = -1;
51+
}
52+
// collapse unallocated adjacent nodes
53+
while (cur.next != null && cur.next.id == -1 && cur.id == -1) {
54+
cur.size += cur.next.size;
55+
cur.next = cur.next.next;
56+
}
57+
return res;
58+
}
59+
60+
private static class Node {
61+
int ind;
62+
Node next;
63+
int size;
64+
int id;
65+
66+
public Node(int i, int sz, int mID) {
67+
ind = i;
68+
size = sz;
69+
id = mID;
70+
}
71+
}
72+
}
73+
74+
/*
75+
* Your Allocator object will be instantiated and called as such:
76+
* Allocator obj = new Allocator(n);
77+
* int param_1 = obj.allocate(size,mID);
78+
* int param_2 = obj.free(mID);
79+
*/
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
2502\. Design Memory Allocator
2+
3+
Medium
4+
5+
You are given an integer `n` representing the size of a **0-indexed** memory array. All memory units are initially free.
6+
7+
You have a memory allocator with the following functionalities:
8+
9+
1. **Allocate** a block of `size` consecutive free memory units and assign it the id `mID`.
10+
2. **Free** all memory units with the given id `mID`.
11+
12+
**Note** that:
13+
14+
* Multiple blocks can be allocated to the same `mID`.
15+
* You should free all the memory units with `mID`, even if they were allocated in different blocks.
16+
17+
Implement the `Allocator` class:
18+
19+
* `Allocator(int n)` Initializes an `Allocator` object with a memory array of size `n`.
20+
* `int allocate(int size, int mID)` Find the **leftmost** block of `size` **consecutive** free memory units and allocate it with the id `mID`. Return the block's first index. If such a block does not exist, return `-1`.
21+
* `int free(int mID)` Free all memory units with the id `mID`. Return the number of memory units you have freed.
22+
23+
**Example 1:**
24+
25+
**Input** ["Allocator", "allocate", "allocate", "allocate", "free", "allocate", "allocate", "allocate", "free", "allocate", "free"] [[10], [1, 1], [1, 2], [1, 3], [2], [3, 4], [1, 1], [1, 1], [1], [10, 2], [7]]
26+
27+
**Output:** [null, 0, 1, 2, 1, 3, 1, 6, 3, -1, 0]
28+
29+
**Explanation:**
30+
31+
Allocator loc = new Allocator(10); // Initialize a memory array of size 10. All memory units are initially free.
32+
33+
loc.allocate(1, 1); // The leftmost block's first index is 0. The memory array becomes [**1**,\_,\_,\_,\_,\_,\_,\_,\_,\_]. We return 0.
34+
35+
loc.allocate(1, 2); // The leftmost block's first index is 1. The memory array becomes [1,**2**,\_,\_,\_,\_,\_,\_,\_,\_]. We return 1.
36+
37+
loc.allocate(1, 3); // The leftmost block's first index is 2. The memory array becomes [1,2,**3**,\_,\_,\_,\_,\_,\_,\_]. We return 2.
38+
39+
loc.free(2); // Free all memory units with mID 2. The memory array becomes [1,\_, 3,\_,\_,\_,\_,\_,\_,\_]. We return 1 since there is only 1 unit with mID 2.
40+
41+
loc.allocate(3, 4); // The leftmost block's first index is 3. The memory array becomes [1,\_,3,**4**,**4**,**4**,\_,\_,\_,\_]. We return 3.
42+
43+
loc.allocate(1, 1); // The leftmost block's first index is 1. The memory array becomes [1,**1**,3,4,4,4,\_,\_,\_,\_]. We return 1.
44+
45+
loc.allocate(1, 1); // The leftmost block's first index is 6. The memory array becomes [1,1,3,4,4,4,**1**,\_,\_,\_]. We return 6.
46+
47+
loc.free(1); // Free all memory units with mID 1. The memory array becomes [\_,\_,3,4,4,4,\_,\_,\_,\_]. We return 3 since there are 3 units with mID 1.
48+
49+
loc.allocate(10, 2); // We can not find any free block with 10 consecutive free memory units, so we return -1.
50+
51+
loc.free(7); // Free all memory units with mID 7. The memory array remains the same since there is no memory unit with mID 7. We return 0.
52+
53+
**Constraints:**
54+
55+
* `1 <= n, size, mID <= 1000`
56+
* At most `1000` calls will be made to `allocate` and `free`.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package g2501_2600.s2501_longest_square_streak_in_an_array;
2+
3+
import static org.hamcrest.CoreMatchers.equalTo;
4+
import static org.hamcrest.MatcherAssert.assertThat;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
class SolutionTest {
9+
@Test
10+
void longestSquareStreak() {
11+
assertThat(new Solution().longestSquareStreak(new int[] {4, 3, 6, 16, 8, 2}), equalTo(3));
12+
}
13+
14+
@Test
15+
void longestSquareStreak2() {
16+
assertThat(new Solution().longestSquareStreak(new int[] {2, 3, 5, 6, 7}), equalTo(-1));
17+
}
18+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package g2501_2600.s2502_design_memory_allocator;
2+
3+
import static org.hamcrest.CoreMatchers.equalTo;
4+
import static org.hamcrest.MatcherAssert.assertThat;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
class AllocatorTest {
9+
@Test
10+
void allocator() {
11+
// Initialize a memory array of size 10. All memory units are initially free.
12+
Allocator loc = new Allocator(10);
13+
// The leftmost block's first index is 0. The memory array becomes [1,_,_,_,_,_,_,_,_,_]. We
14+
// return 0.
15+
assertThat(loc.allocate(1, 1), equalTo(0));
16+
// The leftmost block's first index is 1. The memory array becomes [1,2,_,_,_,_,_,_,_,_]. We
17+
// return 1.
18+
assertThat(loc.allocate(1, 2), equalTo(1));
19+
// The leftmost block's first index is 2. The memory array becomes [1,2,3,_,_,_,_,_,_,_]. We
20+
// return 2.
21+
assertThat(loc.allocate(1, 3), equalTo(2));
22+
// Free all memory units with mID 2. The memory array becomes [1,_, 3,_,_,_,_,_,_,_]. We
23+
// return 1 since there is only 1 unit with mID 2.
24+
loc.free(2);
25+
// The leftmost block's first index is 3. The memory array becomes [1,_,3,4,4,4,_,_,_,_]. We
26+
// return 3.
27+
assertThat(loc.allocate(3, 4), equalTo(3));
28+
// The leftmost block's first index is 1. The memory array becomes [1,1,3,4,4,4,_,_,_,_]. We
29+
// return 1.
30+
assertThat(loc.allocate(1, 1), equalTo(1));
31+
// The leftmost block's first index is 6. The memory array becomes [1,1,3,4,4,4,1,_,_,_]. We
32+
// return 6.
33+
assertThat(loc.allocate(1, 1), equalTo(6));
34+
// Free all memory units with mID 1. The memory array becomes [_,_,3,4,4,4,_,_,_,_]. We
35+
// return 3 since there are 3 units with mID 1.
36+
loc.free(1);
37+
// We can not find any free block with 10 consecutive free memory units, so we return -1.
38+
assertThat(loc.allocate(10, 2), equalTo(-1));
39+
// Free all memory units with mID 7. The memory array remains the same since there is no
40+
// memory unit with mID 7. We return 0.
41+
loc.free(7);
42+
}
43+
}

0 commit comments

Comments
 (0)