Skip to content

Commit d1fa529

Browse files
author
Mauricio Klein
committed
Add solution for challenge #45
1 parent d4aeb8c commit d1fa529

File tree

6 files changed

+75
-0
lines changed

6 files changed

+75
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,4 @@
4444
- [x] [Challenge 42: Depth of a stringified binary tree](challenge-42/)
4545
- [x] [Challenge 43: Contiguous Subarray with Maximum Sum](challenge-43/)
4646
- [x] [Challenge 44: Find the k-th Largest Element in a List](challenge-44/)
47+
- [x] [Challenge 45: Occurrences of a number in a sorted array](challenge-45/)

challenge-45/Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
test:
2+
python test_*.py
3+
4+
.PHONY: test

challenge-45/README.md

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Occurrences of a number in a sorted array
2+
3+
## Description
4+
5+
Given a sorted array, write a function that returns the number of occurences of a number in this array.
6+
7+
**Can you do it in logarithmic time (O(logn))?**
8+
9+
## Example
10+
```
11+
Input:
12+
arr = [1,2,2,2,5,7,9]
13+
k = 2
14+
15+
Output: 3
16+
```

challenge-45/__init__.py

Whitespace-only changes.

challenge-45/solver.py

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#
2+
# Time complexity: O(logn)
3+
# Space complexity: O(1)
4+
#
5+
def occurrences(nums, k):
6+
left = binsearch(nums, k, search_min=True )
7+
right = binsearch(nums, k, search_min=False)
8+
9+
# "k" not found on the array
10+
if left == -1 or right == -1:
11+
return 0
12+
13+
return right - left + 1
14+
15+
def binsearch(nums, k, search_min):
16+
def inbounds(x):
17+
return 0 <= x < len(nums)
18+
19+
left, right = 0, len(nums)
20+
21+
while left <= right:
22+
middle = (left + right) // 2
23+
24+
if k < nums[middle]:
25+
right = middle - 1
26+
elif k > nums[middle]:
27+
left = middle + 1
28+
else:
29+
if search_min:
30+
if inbounds(middle - 1) and nums[middle - 1] == k:
31+
# Proceed looking for the min on the left side
32+
right = middle - 1
33+
else:
34+
return middle
35+
else:
36+
if inbounds(middle + 1) and nums[middle + 1] == k:
37+
# Proceed looking for the max on the right side
38+
left = middle + 1
39+
else:
40+
return middle
41+
42+
return -1

challenge-45/test_solver.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import unittest
2+
from solver import occurrences
3+
4+
class TestSolver(unittest.TestCase):
5+
def test_occurrences(self):
6+
self.assertEqual(occurrences([1, 2, 2, 2, 5, 7, 9], k=2), 3)
7+
self.assertEqual(occurrences([1, 2, 5, 7, 8, 9, 9], k=9), 2)
8+
self.assertEqual(occurrences([1, 1, 2, 5, 7, 8, 9], k=1), 2)
9+
self.assertEqual(occurrences([1, 2, 3, 5, 7, 8, 9], k=0), 0)
10+
11+
if __name__ == "__main__":
12+
unittest.main()

0 commit comments

Comments
 (0)