Skip to content

Commit 57abf28

Browse files
committed
adding udpates
1 parent fe12b2d commit 57abf28

4 files changed

Lines changed: 213 additions & 0 deletions

File tree

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
from typing import List, Union, Collection, Mapping, Optional
2+
from abc import ABC, abstractmethod
3+
import random
4+
5+
6+
class RandomizedSet:
7+
8+
def __init__(self):
9+
self.data_map = {} # dictionary, aka map, aka hashtable, aka hashmap
10+
self.data = [] # list aka array
11+
12+
def insert(self, val: int) -> bool:
13+
14+
# the problem indicates we need to return False if the item
15+
# is already in the RandomizedSet---checking if it's in the
16+
# dictionary is on average O(1) where as
17+
# checking the array is on average O(n)
18+
if val in self.data_map:
19+
return False
20+
21+
# add the element to the dictionary. Setting the value as the
22+
# length of the list will accurately point to the index of the
23+
# new element. (len(some_list) is equal to the index of the last item +1)
24+
self.data_map[val] = len(self.data)
25+
26+
# add to the list
27+
self.data.append(val)
28+
29+
return True
30+
31+
def remove(self, val: int) -> bool:
32+
33+
# again, if the item is not in the data_map, return False.
34+
# we check the dictionary instead of the list due to lookup complexity
35+
if not val in self.data_map:
36+
return False
37+
38+
# essentially, we're going to move the last element in the list
39+
# into the location of the element we want to remove.
40+
# this is a significantly more efficient operation than the obvious
41+
# solution of removing the item and shifting the values of every item
42+
# in the dicitionary to match their new position in the list
43+
last_elem_in_list = self.data[-1]
44+
index_of_elem_to_remove = self.data_map[val]
45+
46+
self.data_map[last_elem_in_list] = index_of_elem_to_remove
47+
self.data[index_of_elem_to_remove] = last_elem_in_list
48+
49+
# change the last element in the list to now be the value of the element
50+
# we want to remove
51+
self.data[-1] = val
52+
53+
# remove the last element in the list
54+
self.data.pop()
55+
56+
# remove the element to be removed from the dictionary
57+
self.data_map.pop(val)
58+
return True
59+
60+
def getRandom(self) -> int:
61+
# if running outside of leetcode, you need to `import random`.
62+
# random.choice will randomly select an element from the list of data.
63+
return random.choice(self.data)
64+
65+
66+
67+
# Your RandomizedSet object will be instantiated and called as such:
68+
# obj = RandomizedSet()
69+
# param_1 = obj.insert(val)
70+
# param_2 = obj.remove(val)
71+
# param_3 = obj.getRandom()
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
class RandomizedSet {
2+
private dataMap: Map<number, number>; // dictionary, aka map, aka hashtable, aka hashmap
3+
private data: number[]; // list aka array
4+
5+
constructor() {
6+
this.dataMap = new Map();
7+
this.data = [];
8+
}
9+
10+
insert(val: number): boolean {
11+
// the problem indicates we need to return False if the item
12+
// is already in the RandomizedSet---checking if it's in the
13+
// dictionary is on average O(1) where as
14+
// checking the array is on average O(n)
15+
if (this.dataMap.has(val)) {
16+
return false;
17+
}
18+
19+
// add the element to the dictionary. Setting the value as the
20+
// length of the list will accurately point to the index of the
21+
// new element. (len(some_list) is equal to the index of the last item +1)
22+
this.dataMap.set(val, this.data.length);
23+
24+
// add to the list
25+
this.data.push(val);
26+
27+
return true;
28+
}
29+
30+
remove(val: number): boolean {
31+
// again, if the item is not in the dataMap, return false.
32+
// we check the dictionary instead of the list due to lookup complexity
33+
if (!this.dataMap.has(val)) {
34+
return false;
35+
}
36+
37+
// essentially, we're going to move the last element in the list
38+
// into the location of the element we want to remove.
39+
// this is a significantly more efficient operation than the obvious
40+
// solution of removing the item and shifting the values of every item
41+
// in the dictionary to match their new position in the list
42+
const lastElemInList = this.data[this.data.length - 1];
43+
const indexOfElemToRemove = this.dataMap.get(val)!;
44+
45+
this.dataMap.set(lastElemInList, indexOfElemToRemove);
46+
this.data[indexOfElemToRemove] = lastElemInList;
47+
48+
// change the last element in the list to now be the value of the element
49+
// we want to remove
50+
this.data[this.data.length - 1] = val;
51+
52+
// remove the last element in the list
53+
this.data.pop();
54+
55+
// remove the element to be removed from the dictionary
56+
this.dataMap.delete(val);
57+
return true;
58+
}
59+
60+
getRandom(): number {
61+
// random.choice will randomly select an element from the list of data.
62+
return this.data[Math.floor(Math.random() * this.data.length)];
63+
}
64+
}
65+
66+
/**
67+
* Your RandomizedSet object will be instantiated and called as such:
68+
* var obj = new RandomizedSet()
69+
* var param_1 = obj.insert(val)
70+
* var param_2 = obj.remove(val)
71+
* var param_3 = obj.getRandom()
72+
*/
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import unittest
2+
from src.my_project.interviews.top_150_questions_round_22\
3+
.ex_12_insert_delete_get_random import RandomizedSet
4+
5+
class InsertAndDeleteGetRandomTestCase(unittest.TestCase):
6+
7+
def test_first_case(self):
8+
randomized_set = RandomizedSet()
9+
self.assertTrue(randomized_set.insert(1)) # Inserts 1, returns true
10+
self.assertFalse(randomized_set.remove(2)) # 2 not present, returns false
11+
self.assertTrue(randomized_set.insert(2)) # Inserts 2, returns true
12+
self.assertIn(randomized_set.getRandom(), [1, 2]) # getRandom returns 1 or 2
13+
self.assertTrue(randomized_set.remove(1)) # Removes 1, returns true
14+
self.assertFalse(randomized_set.insert(2)) # 2 already present, returns false
15+
self.assertEqual(randomized_set.getRandom(), 2) # Only 2 in set
16+
17+
def test_insert_duplicate(self):
18+
randomized_set = RandomizedSet()
19+
self.assertTrue(randomized_set.insert(5))
20+
self.assertFalse(randomized_set.insert(5)) # duplicate
21+
22+
def test_remove_nonexistent(self):
23+
randomized_set = RandomizedSet()
24+
self.assertFalse(randomized_set.remove(99))
25+
26+
def test_remove_existing(self):
27+
randomized_set = RandomizedSet()
28+
randomized_set.insert(10)
29+
self.assertTrue(randomized_set.remove(10))
30+
self.assertFalse(randomized_set.remove(10)) # already removed
31+
32+
def test_get_random_single_element(self):
33+
randomized_set = RandomizedSet()
34+
randomized_set.insert(42)
35+
self.assertEqual(randomized_set.getRandom(), 42)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import unittest
2+
from src.my_project.interviews.top_150_questions_round_23\
3+
.ex_12_insert_delete_get_random import RandomizedSet
4+
5+
class InsertAndDeleteGetRandomTestCase(unittest.TestCase):
6+
7+
def test_first_case(self):
8+
randomized_set = RandomizedSet()
9+
self.assertTrue(randomized_set.insert(1)) # Inserts 1, returns true
10+
self.assertFalse(randomized_set.remove(2)) # 2 not present, returns false
11+
self.assertTrue(randomized_set.insert(2)) # Inserts 2, returns true
12+
self.assertIn(randomized_set.getRandom(), [1, 2]) # getRandom returns 1 or 2
13+
self.assertTrue(randomized_set.remove(1)) # Removes 1, returns true
14+
self.assertFalse(randomized_set.insert(2)) # 2 already present, returns false
15+
self.assertEqual(randomized_set.getRandom(), 2) # Only 2 in set
16+
17+
def test_insert_duplicate(self):
18+
randomized_set = RandomizedSet()
19+
self.assertTrue(randomized_set.insert(5))
20+
self.assertFalse(randomized_set.insert(5)) # duplicate
21+
22+
def test_remove_nonexistent(self):
23+
randomized_set = RandomizedSet()
24+
self.assertFalse(randomized_set.remove(99))
25+
26+
def test_remove_existing(self):
27+
randomized_set = RandomizedSet()
28+
randomized_set.insert(10)
29+
self.assertTrue(randomized_set.remove(10))
30+
self.assertFalse(randomized_set.remove(10)) # already removed
31+
32+
def test_get_random_single_element(self):
33+
randomized_set = RandomizedSet()
34+
randomized_set.insert(42)
35+
self.assertEqual(randomized_set.getRandom(), 42)

0 commit comments

Comments
 (0)