Skip to content

Commit 1860539

Browse files
Merge pull request #165 from marcosurbanski/setup
Setup
2 parents 917ea7e + f57ebef commit 1860539

File tree

4 files changed

+161
-30
lines changed

4 files changed

+161
-30
lines changed
Lines changed: 97 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,107 @@
1+
"""
2+
Este código implementa duas versões de busca exponencial em arrays ordenados,
3+
uma usando acesso direto ao array e outra simulando o ArrayReader do LeetCode 702.
14
2-
def binary_search(nums, n, low, high):
3-
while low < high:
4-
mid = int((low + high)/2)
5+
Objetivo:
6+
- A classe Solution implementa a busca exponencial diretamente em um array normal.
7+
- A classe Solution1 implementa a busca exponencial em um array de tamanho desconhecido
8+
usando a interface ArrayReader, combinando exponential search com binary search.
9+
- A classe ArrayReader simula a interface usada no LeetCode, retornando um valor
10+
muito grande caso o índice acessado esteja fora do limite.
11+
"""
512

6-
if nums[mid] == n:
7-
return mid
8-
elif nums[mid] < n:
9-
low = mid+1
10-
else:
11-
high = mid
12-
return -1
13+
# Simula o ArrayReader do LeetCode
14+
class ArrayReader:
15+
def __init__(self, arr):
16+
# Armazena o array interno
17+
self.arr = arr
1318

19+
def get(self, index: int) -> int:
20+
# Se o índice está dentro do array, retorna o valor correspondente
21+
if 0 <= index < len(self.arr):
22+
return self.arr[index]
23+
# Caso contrário, retorna um valor muito grande (simulando índice fora do array)
24+
return 2**31 -1
1425

15-
def exponencial_search(arr, target):
16-
if arr[0] == target:
17-
return 0
18-
n = len(arr)
19-
i = 1
2026

21-
while i < n and arr[i] < target:
22-
i *= 2
27+
# Implementação de Exponential Search com acesso direto ao array
28+
class Solution():
29+
@staticmethod
30+
def binary_search(nums, n, low, high):
31+
"""
32+
Busca binária em um array ordenado entre os índices low e high.
33+
Retorna o índice do elemento n ou -1 se não encontrado.
34+
"""
35+
while low < high:
36+
# Calcula o índice do meio do intervalo
37+
mid = int((low + high)/2)
2338

24-
if arr[i] == target:
25-
return i
39+
if nums[mid] == n:
40+
# Encontrou o elemento
41+
return mid
42+
elif nums[mid] < n:
43+
# Elemento está à direita
44+
low = mid + 1
45+
else:
46+
# Elemento está à esquerda
47+
high = mid
48+
# Não encontrou o elemento
49+
return -1
2650

27-
return binary_search(arr, target, i//2, min(i, n-1))
51+
def exponencial_search(self, arr, target):
52+
"""
53+
Busca exponencial em um array ordenado.
54+
Primeiro encontra um intervalo em que o target pode estar,
55+
depois aplica busca binária nesse intervalo.
56+
"""
57+
# Caso o primeiro elemento seja o target
58+
if arr[0] == target:
59+
return 0
60+
n = len(arr)
61+
i = 1
2862

63+
# Dobrar o índice até ultrapassar o target ou o tamanho do array
64+
while i < n and arr[i] < target:
65+
i *= 2
2966

30-
d = [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]
31-
target = 14
32-
result = exponencial_search(d, target)
67+
# Caso o elemento esteja exatamente no índice encontrado
68+
if arr[i] == target:
69+
return i
3370

34-
print(f"Element found at index {result}")
71+
# Aplicar busca binária no intervalo encontrado
72+
return Solution.binary_search(arr, target, i//2, min(i, n-1))
73+
74+
75+
# Implementação de Exponential Search usando ArrayReader (tamanho desconhecido)
76+
class Solution1():
77+
def search(self, reader: ArrayReader, target: int) -> int:
78+
# Caso base: verifica o primeiro elemento
79+
if reader.get(0) == target:
80+
return 0
81+
82+
# 1) Busca exponencial para encontrar o intervalo
83+
i = 1
84+
while reader.get(i) < target:
85+
# Dobrar o índice até encontrar valor >= target
86+
i *= 2
87+
88+
# 2) Busca binária dentro do intervalo [i//2, i]
89+
low, high = i // 2, i
90+
while low <= high:
91+
# Índice do meio do intervalo
92+
mid = (low + high) // 2
93+
# Valor no índice mid
94+
val = reader.get(mid)
95+
96+
if val == target:
97+
# Encontrou o target
98+
return mid
99+
elif val > target:
100+
# Target está à esquerda
101+
high = mid - 1
102+
else:
103+
# Target está à direita
104+
low = mid + 1
105+
106+
# Target não encontrado
107+
return -1

algorithms_project/algorithms/arrays/len_last_word.py

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,52 @@
1+
"""
2+
Este código implementa duas soluções diferentes para o problema
3+
"Length of Last Word" (LeetCode 58).
4+
5+
Objetivo:
6+
Dada uma string que contém palavras e espaços, retornar o comprimento
7+
da última palavra (sequência de caracteres não vazios separados por espaços).
8+
9+
A classe Solution resolve o problema manualmente usando ponteiros (left e right).
10+
A classe Solution2 resolve de forma mais simples usando o método split() do Python.
11+
"""
12+
13+
114
class Solution():
215
def lengthOfLastWord(self, string_word: str) -> int:
316
"""
417
:type s: str
518
:rtype: int
619
"""
7-
left, right = 0, 0
20+
# Incializa os poneiros left e right em 0
21+
left, right = 0, 0
22+
# Lista para armazenar as palavras encontradas
823
words = []
924

25+
# Loop percorre a string até o final
1026
while right < len(string_word):
27+
# Se o caractere atual não for espaço, move o ponteiro da direita
1128
if string_word[right] != ' ':
12-
right += 1
29+
right += 1
1330
else:
31+
# Caso encontre espaço, adiciona a palavra entre left e right
1432
words.append(string_word[left:right])
33+
# Avança o ponteiro right para pular o espaço
1534
right += 1
35+
# Atualiza o ponteiro left para o próximo inicio de palavra
1636
left = right
17-
37+
# após o loop, adiciona a ultima palavra capturada
1838
words.append(string_word[left:right])
19-
39+
# Retorna o tamanho da última palavra capturada
40+
return len(words[-1])
41+
42+
43+
class Solution2():
44+
def lengthOfLastWord(self, string_word: str) -> int:
45+
"""
46+
:type s: str
47+
:rtype: int
48+
"""
49+
# Usa split() para separar a string em palavras igorando múltiplos espaços
50+
words = string_word.split()
51+
# Retorna o comprimento da última palavra
2052
return len(words[-1])
21-
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import pytest
2+
from algorithms_project.algorithms.arrays.exponential_search import Solution, ArrayReader
3+
4+
5+
@pytest.mark.parametrize("array,target,expected", [
6+
([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
7+
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
8+
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
9+
36, 37, 38, 39, 40], 14, 13),
10+
])
11+
def test_exponential_search(array, target, expected):
12+
assert Solution().exponencial_search(array, target) == expected
13+
14+
@pytest.mark.parametrize("array,target,expected", [
15+
([-1, 0, 3, 5, 9, 12], 9, 4),
16+
([-1, 0, 3, 5, 9, 12], 2, -1),
17+
])
18+
def test_exponential_search_unknown_size(array, target, expected):
19+
reader = ArrayReader(array)
20+
assert Solution().exponencial_search(array, target) == expected
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
import pytest
2-
from algorithms.arrays.len_last_word import Solution
2+
from algorithms.arrays.len_last_word import Solution, Solution2
33

44

55
@pytest.mark.parametrize("string_word,expected", [
66
("Hello World", 5),
77
])
88
def test_lengthOfLastWord(string_word, expected):
99
assert Solution().lengthOfLastWord(string_word) == expected
10+
11+
12+
@pytest.mark.parametrize("string_word,expected", [
13+
("Hello World", 5),
14+
])
15+
def test_lengthOfLastWord1(string_word, expected):
16+
assert Solution2().lengthOfLastWord(string_word) == expected

0 commit comments

Comments
 (0)