Skip to content

Commit df6825d

Browse files
authored
Added tasks 458, 459, 460, 461.
1 parent 5bf0b85 commit df6825d

File tree

13 files changed

+424
-0
lines changed

13 files changed

+424
-0
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ implementation 'com.github.javadev:leetcode-in-kotlin:1.7'
275275
| <!-- --> | <!-- --> | <!-- --> | <!-- --> | <!-- --> | <!-- -->
276276
|-|-|-|-|-|-
277277
| 0110 |[Balanced Binary Tree](src/main/kotlin/g0101_0200/s0110_balanced_binary_tree/Solution.kt)| Easy | Depth_First_Search, Tree, Binary_Tree | 310 | 63.63
278+
| 0459 |[Repeated Substring Pattern](src/main/kotlin/g0401_0500/s0459_repeated_substring_pattern/Solution.kt)| Easy | String, String_Matching | 201 | 100.00
278279

279280
#### Day 3
280281

@@ -941,6 +942,7 @@ implementation 'com.github.javadev:leetcode-in-kotlin:1.7'
941942
| 0191 |[Number of 1 Bits](src/main/kotlin/g0101_0200/s0191_number_of_1_bits/Solution.kt)| Easy | Top_Interview_Questions, Bit_Manipulation | 237 | 68.44
942943
| 0389 |[Find the Difference](src/main/kotlin/g0301_0400/s0389_find_the_difference/Solution.kt)| Easy | String, Hash_Table, Sorting, Bit_Manipulation | 256 | 64.81
943944
| 0190 |[Reverse Bits](src/main/kotlin/g0101_0200/s0190_reverse_bits/Solution.kt)| Easy | Top_Interview_Questions, Bit_Manipulation, Divide_and_Conquer | 198 | 81.82
945+
| 0461 |[Hamming Distance](src/main/kotlin/g0401_0500/s0461_hamming_distance/Solution.kt)| Easy | Bit_Manipulation | 150 | 96.15
944946
| 0338 |[Counting Bits](src/main/kotlin/g0301_0400/s0338_counting_bits/Solution.kt)| Easy | Top_100_Liked_Questions, Dynamic_Programming, Bit_Manipulation | 186 | 99.26
945947
| 0371 |[Sum of Two Integers](src/main/kotlin/g0301_0400/s0371_sum_of_two_integers/Solution.kt)| Medium | Top_Interview_Questions, Math, Bit_Manipulation | 129 | 95.45
946948
| 0029 |[Divide Two Integers](src/main/kotlin/g0001_0100/s0029_divide_two_integers/Solution.kt)| Medium | Top_Interview_Questions, Math, Bit_Manipulation | 281 | 31.67
@@ -1638,6 +1640,10 @@ implementation 'com.github.javadev:leetcode-in-kotlin:1.7'
16381640
| 0560 |[Subarray Sum Equals K](src/main/kotlin/g0501_0600/s0560_subarray_sum_equals_k/Solution.kt)| Medium | Top_100_Liked_Questions, Array, Hash_Table, Prefix_Sum, Data_Structure_II_Day_5_Array | 692 | 53.27
16391641
| 0543 |[Diameter of Binary Tree](src/main/kotlin/g0501_0600/s0543_diameter_of_binary_tree/Solution.kt)| Easy | Top_100_Liked_Questions, Depth_First_Search, Tree, Binary_Tree, Level_2_Day_7_Tree, Udemy_Tree_Stack_Queue | 307 | 43.93
16401642
| 0494 |[Target Sum](src/main/kotlin/g0401_0500/s0494_target_sum/Solution.kt)| Medium | Top_100_Liked_Questions, Array, Dynamic_Programming, Backtracking | 308 | 89.61
1643+
| 0461 |[Hamming Distance](src/main/kotlin/g0401_0500/s0461_hamming_distance/Solution.kt)| Easy | Bit_Manipulation, Udemy_Bit_Manipulation | 150 | 96.15
1644+
| 0460 |[LFU Cache](src/main/kotlin/g0401_0500/s0460_lfu_cache/LFUCache.kt)| Hard | Hash_Table, Design, Linked_List, Doubly_Linked_List | 1143 | 100.00
1645+
| 0459 |[Repeated Substring Pattern](src/main/kotlin/g0401_0500/s0459_repeated_substring_pattern/Solution.kt)| Easy | String, String_Matching, Programming_Skills_II_Day_2 | 201 | 100.00
1646+
| 0458 |[Poor Pigs](src/main/kotlin/g0401_0500/s0458_poor_pigs/Solution.kt)| Hard | Dynamic_Programming, Math, Combinatorics | 133 | 80.00
16411647
| 0457 |[Circular Array Loop](src/main/kotlin/g0401_0500/s0457_circular_array_loop/Solution.kt)| Medium | Array, Hash_Table, Two_Pointers | 143 | 100.00
16421648
| 0456 |[132 Pattern](src/main/kotlin/g0401_0500/s0456_132_pattern/Solution.kt)| Medium | Array, Binary_Search, Stack, Ordered_Set, Monotonic_Stack, Udemy_Arrays | 434 | 100.00
16431649
| 0455 |[Assign Cookies](src/main/kotlin/g0401_0500/s0455_assign_cookies/Solution.kt)| Easy | Array, Sorting, Greedy | 260 | 96.67
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package g0401_0500.s0458_poor_pigs
2+
3+
// #Hard #Dynamic_Programming #Math #Combinatorics
4+
// #2022_12_27_Time_133_ms_(80.00%)_Space_32.8_MB_(80.00%)
5+
6+
@Suppress("NAME_SHADOWING")
7+
class Solution {
8+
fun poorPigs(buckets: Int, minutesToDie: Int, minutesToTest: Int): Int {
9+
var buckets = buckets
10+
if (buckets-- == 1) {
11+
return 0
12+
}
13+
val base = minutesToTest / minutesToDie + 1
14+
var count = 0
15+
while (buckets > 0) {
16+
buckets /= base
17+
count++
18+
}
19+
return count
20+
}
21+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
458\. Poor Pigs
2+
3+
Hard
4+
5+
There are `buckets` buckets of liquid, where **exactly one** of the buckets is poisonous. To figure out which one is poisonous, you feed some number of (poor) pigs the liquid to see whether they will die or not. Unfortunately, you only have `minutesToTest` minutes to determine which bucket is poisonous.
6+
7+
You can feed the pigs according to these steps:
8+
9+
1. Choose some live pigs to feed.
10+
2. For each pig, choose which buckets to feed it. The pig will consume all the chosen buckets simultaneously and will take no time.
11+
3. Wait for `minutesToDie` minutes. You may **not** feed any other pigs during this time.
12+
4. After `minutesToDie` minutes have passed, any pigs that have been fed the poisonous bucket will die, and all others will survive.
13+
5. Repeat this process until you run out of time.
14+
15+
Given `buckets`, `minutesToDie`, and `minutesToTest`, return _the **minimum** number of pigs needed to figure out which bucket is poisonous within the allotted time_.
16+
17+
**Example 1:**
18+
19+
**Input:** buckets = 1000, minutesToDie = 15, minutesToTest = 60
20+
21+
**Output:** 5
22+
23+
**Example 2:**
24+
25+
**Input:** buckets = 4, minutesToDie = 15, minutesToTest = 15
26+
27+
**Output:** 2
28+
29+
**Example 3:**
30+
31+
**Input:** buckets = 4, minutesToDie = 15, minutesToTest = 30
32+
33+
**Output:** 2
34+
35+
**Constraints:**
36+
37+
* `1 <= buckets <= 1000`
38+
* `1 <= minutesToDie <= minutesToTest <= 100`
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package g0401_0500.s0459_repeated_substring_pattern
2+
3+
// #Easy #String #String_Matching #Programming_Skills_II_Day_2
4+
// #2022_12_27_Time_201_ms_(100.00%)_Space_36.2_MB_(89.29%)
5+
6+
class Solution {
7+
fun repeatedSubstringPattern(s: String): Boolean {
8+
val n = s.length
9+
if (n < 2) {
10+
return false
11+
}
12+
var i = 0
13+
while (i < (n + 1) / 2) {
14+
if (n % (i + 1) != 0) {
15+
i++
16+
continue
17+
}
18+
var match = true
19+
val substring = s.substring(0, i + 1)
20+
var skippedI = i
21+
var j = i + 1
22+
while (j < n) {
23+
if (s.substring(j, j + i + 1) != substring) {
24+
match = false
25+
break
26+
}
27+
skippedI += i + 1
28+
j += i + 1
29+
}
30+
if (match) {
31+
return true
32+
}
33+
i = skippedI
34+
i++
35+
}
36+
return false
37+
}
38+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
459\. Repeated Substring Pattern
2+
3+
Easy
4+
5+
Given a string `s`, check if it can be constructed by taking a substring of it and appending multiple copies of the substring together.
6+
7+
**Example 1:**
8+
9+
**Input:** s = "abab"
10+
11+
**Output:** true
12+
13+
**Explanation:** It is the substring "ab" twice.
14+
15+
**Example 2:**
16+
17+
**Input:** s = "aba"
18+
19+
**Output:** false
20+
21+
**Example 3:**
22+
23+
**Input:** s = "abcabcabcabc"
24+
25+
**Output:** true
26+
27+
**Explanation:** It is the substring "abc" four times or the substring "abcabc" twice.
28+
29+
**Constraints:**
30+
31+
* <code>1 <= s.length <= 10<sup>4</sup></code>
32+
* `s` consists of lowercase English letters.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package g0401_0500.s0460_lfu_cache
2+
3+
// #Hard #Hash_Table #Design #Linked_List #Doubly_Linked_List
4+
// #2022_12_27_Time_1143_ms_(100.00%)_Space_151.2_MB_(66.67%)
5+
6+
class LFUCache(capacity: Int) {
7+
private class Node {
8+
var prev: Node? = null
9+
var next: Node? = null
10+
var key = -1
11+
var `val` = 0
12+
var freq = 0
13+
}
14+
15+
private val endOfBlock: MutableMap<Int, Node?>
16+
private val map: MutableMap<Int, Node>
17+
private val capacity: Int
18+
private val linkedList: Node
19+
20+
init {
21+
endOfBlock = HashMap()
22+
map = HashMap()
23+
this.capacity = capacity
24+
linkedList = Node()
25+
}
26+
27+
operator fun get(key: Int): Int {
28+
if (map.containsKey(key)) {
29+
val newEndNode = map[key]
30+
val endNode: Node?
31+
val currEndNode = endOfBlock[newEndNode!!.freq]
32+
if (currEndNode === newEndNode) {
33+
findNewEndOfBlock(newEndNode)
34+
if (currEndNode.next == null || currEndNode.next!!.freq > newEndNode.freq + 1) {
35+
newEndNode.freq++
36+
endOfBlock[newEndNode.freq] = newEndNode
37+
return newEndNode.`val`
38+
}
39+
}
40+
if (newEndNode.next != null) {
41+
newEndNode.next!!.prev = newEndNode.prev
42+
}
43+
newEndNode.prev!!.next = newEndNode.next
44+
newEndNode.freq++
45+
endNode = if (currEndNode!!.next == null || currEndNode.next!!.freq > newEndNode.freq) {
46+
currEndNode
47+
} else {
48+
endOfBlock[newEndNode.freq]
49+
}
50+
endOfBlock[newEndNode.freq] = newEndNode
51+
if (endNode!!.next != null) {
52+
endNode.next!!.prev = newEndNode
53+
}
54+
newEndNode.next = endNode.next
55+
endNode.next = newEndNode
56+
newEndNode.prev = endNode
57+
return newEndNode.`val`
58+
}
59+
return -1
60+
}
61+
62+
fun put(key: Int, value: Int) {
63+
val endNode: Node?
64+
val newEndNode: Node
65+
if (capacity == 0) {
66+
return
67+
}
68+
if (map.containsKey(key)) {
69+
map[key]!!.`val` = value
70+
get(key)
71+
} else {
72+
if (map.size == capacity) {
73+
val toDelete = linkedList.next
74+
map.remove(toDelete!!.key)
75+
if (toDelete.next != null) {
76+
toDelete.next!!.prev = linkedList
77+
}
78+
linkedList.next = toDelete.next
79+
if (endOfBlock[toDelete.freq] === toDelete) {
80+
endOfBlock.remove(toDelete.freq)
81+
}
82+
}
83+
newEndNode = Node()
84+
newEndNode.key = key
85+
newEndNode.`val` = value
86+
newEndNode.freq = 1
87+
map[key] = newEndNode
88+
endNode = endOfBlock.getOrDefault(1, linkedList)
89+
endOfBlock[1] = newEndNode
90+
if (endNode!!.next != null) {
91+
endNode.next!!.prev = newEndNode
92+
}
93+
newEndNode.next = endNode.next
94+
endNode.next = newEndNode
95+
newEndNode.prev = endNode
96+
}
97+
}
98+
99+
private fun findNewEndOfBlock(node: Node?) {
100+
val prev = node!!.prev
101+
if (prev!!.freq == node.freq) {
102+
endOfBlock[node.freq] = prev
103+
} else {
104+
endOfBlock.remove(node.freq)
105+
}
106+
}
107+
}
108+
109+
/*
110+
* Your LFUCache object will be instantiated and called as such:
111+
* var obj = LFUCache(capacity)
112+
* var param_1 = obj.get(key)
113+
* obj.put(key,value)
114+
*/
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
460\. LFU Cache
2+
3+
Hard
4+
5+
Design and implement a data structure for a [Least Frequently Used (LFU)](https://en.wikipedia.org/wiki/Least_frequently_used) cache.
6+
7+
Implement the `LFUCache` class:
8+
9+
* `LFUCache(int capacity)` Initializes the object with the `capacity` of the data structure.
10+
* `int get(int key)` Gets the value of the `key` if the `key` exists in the cache. Otherwise, returns `-1`.
11+
* `void put(int key, int value)` Update the value of the `key` if present, or inserts the `key` if not already present. When the cache reaches its `capacity`, it should invalidate and remove the **least frequently used** key before inserting a new item. For this problem, when there is a **tie** (i.e., two or more keys with the same frequency), the **least recently used** `key` would be invalidated.
12+
13+
To determine the least frequently used key, a **use counter** is maintained for each key in the cache. The key with the smallest **use counter** is the least frequently used key.
14+
15+
When a key is first inserted into the cache, its **use counter** is set to `1` (due to the `put` operation). The **use counter** for a key in the cache is incremented either a `get` or `put` operation is called on it.
16+
17+
The functions `get` and `put` must each run in `O(1)` average time complexity.
18+
19+
**Example 1:**
20+
21+
**Input**
22+
23+
["LFUCache", "put", "put", "get", "put", "get", "get", "put", "get", "get", "get"]
24+
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [3], [4, 4], [1], [3], [4]]
25+
26+
**Output:** [null, null, null, 1, null, -1, 3, null, -1, 3, 4]
27+
28+
**Explanation:**
29+
30+
// cnt(x) = the use counter for key x
31+
32+
// cache=[] will show the last used order for tiebreakers (leftmost element is most recent)
33+
34+
LFUCache lfu = new LFUCache(2);
35+
lfu.put(1, 1); // cache=[1,_], cnt(1)=1
36+
lfu.put(2, 2); // cache=[2,1], cnt(2)=1, cnt(1)=1
37+
lfu.get(1); // return 1
38+
// cache=[1,2], cnt(2)=1, cnt(1)=2
39+
lfu.put(3, 3); // 2 is the LFU key because cnt(2)=1 is the smallest, invalidate 2.
40+
// cache=[3,1], cnt(3)=1, cnt(1)=2
41+
lfu.get(2); // return -1 (not found)
42+
lfu.get(3); // return 3
43+
// cache=[3,1], cnt(3)=2, cnt(1)=2
44+
lfu.put(4, 4); // Both 1 and 3 have the same cnt, but 1 is LRU, invalidate 1.
45+
// cache=[4,3], cnt(4)=1, cnt(3)=2
46+
lfu.get(1); // return -1 (not found)
47+
lfu.get(3); // return 3
48+
// cache=[3,4], cnt(4)=1, cnt(3)=3
49+
lfu.get(4); // return 4
50+
// cache=[3,4], cnt(4)=2, cnt(3)=3
51+
52+
**Constraints:**
53+
54+
* <code>0 <= capacity <= 10<sup>4</sup></code>
55+
* <code>0 <= key <= 10<sup>5</sup></code>
56+
* <code>0 <= value <= 10<sup>9</sup></code>
57+
* At most <code>2 * 10<sup>5</sup></code> calls will be made to `get` and `put`.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package g0401_0500.s0461_hamming_distance
2+
3+
// #Easy #Bit_Manipulation #Udemy_Bit_Manipulation
4+
// #2022_12_27_Time_150_ms_(96.15%)_Space_32.9_MB_(92.31%)
5+
6+
class Solution {
7+
fun hammingDistance(x: Int, y: Int): Int {
8+
return Integer.bitCount(x xor y)
9+
}
10+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
461\. Hamming Distance
2+
3+
Easy
4+
5+
The [Hamming distance](https://en.wikipedia.org/wiki/Hamming_distance) between two integers is the number of positions at which the corresponding bits are different.
6+
7+
Given two integers `x` and `y`, return _the **Hamming distance** between them_.
8+
9+
**Example 1:**
10+
11+
**Input:** x = 1, y = 4
12+
13+
**Output:** 2
14+
15+
**Explanation:** 1 (0 0 0 1) 4 (0 1 0 0) ↑ ↑ The above arrows point to positions where the corresponding bits are different.
16+
17+
**Example 2:**
18+
19+
**Input:** x = 3, y = 1
20+
21+
**Output:** 1
22+
23+
**Constraints:**
24+
25+
* <code>0 <= x, y <= 2<sup>31</sup> - 1</code>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package g0401_0500.s0458_poor_pigs
2+
3+
import org.hamcrest.CoreMatchers.equalTo
4+
import org.hamcrest.MatcherAssert.assertThat
5+
import org.junit.jupiter.api.Test
6+
7+
internal class SolutionTest {
8+
@Test
9+
fun poorPigs() {
10+
assertThat(Solution().poorPigs(1000, 15, 60), equalTo(5))
11+
}
12+
13+
@Test
14+
fun poorPigs2() {
15+
assertThat(Solution().poorPigs(4, 15, 15), equalTo(2))
16+
}
17+
18+
@Test
19+
fun poorPigs3() {
20+
assertThat(Solution().poorPigs(4, 15, 30), equalTo(2))
21+
}
22+
}

0 commit comments

Comments
 (0)