Skip to content
Merged

Setup #165

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 97 additions & 24 deletions algorithms_project/algorithms/arrays/exponential_search.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,107 @@
"""
Este código implementa duas versões de busca exponencial em arrays ordenados,
uma usando acesso direto ao array e outra simulando o ArrayReader do LeetCode 702.

def binary_search(nums, n, low, high):
while low < high:
mid = int((low + high)/2)
Objetivo:
- A classe Solution implementa a busca exponencial diretamente em um array normal.
- A classe Solution1 implementa a busca exponencial em um array de tamanho desconhecido
usando a interface ArrayReader, combinando exponential search com binary search.
- A classe ArrayReader simula a interface usada no LeetCode, retornando um valor
muito grande caso o índice acessado esteja fora do limite.
"""

if nums[mid] == n:
return mid
elif nums[mid] < n:
low = mid+1
else:
high = mid
return -1
# Simula o ArrayReader do LeetCode
class ArrayReader:
def __init__(self, arr):
# Armazena o array interno
self.arr = arr

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

def exponencial_search(arr, target):
if arr[0] == target:
return 0
n = len(arr)
i = 1

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

if arr[i] == target:
return i
if nums[mid] == n:
# Encontrou o elemento
return mid
elif nums[mid] < n:
# Elemento está à direita
low = mid + 1
else:
# Elemento está à esquerda
high = mid
# Não encontrou o elemento
return -1

return binary_search(arr, target, i//2, min(i, n-1))
def exponencial_search(self, arr, target):
"""
Busca exponencial em um array ordenado.
Primeiro encontra um intervalo em que o target pode estar,
depois aplica busca binária nesse intervalo.
"""
# Caso o primeiro elemento seja o target
if arr[0] == target:
return 0
n = len(arr)
i = 1

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

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

print(f"Element found at index {result}")
# Aplicar busca binária no intervalo encontrado
return Solution.binary_search(arr, target, i//2, min(i, n-1))


# Implementação de Exponential Search usando ArrayReader (tamanho desconhecido)
class Solution1():
def search(self, reader: ArrayReader, target: int) -> int:
# Caso base: verifica o primeiro elemento
if reader.get(0) == target:
return 0

# 1) Busca exponencial para encontrar o intervalo
i = 1
while reader.get(i) < target:
# Dobrar o índice até encontrar valor >= target
i *= 2

# 2) Busca binária dentro do intervalo [i//2, i]
low, high = i // 2, i
while low <= high:
# Índice do meio do intervalo
mid = (low + high) // 2
# Valor no índice mid
val = reader.get(mid)

if val == target:
# Encontrou o target
return mid
elif val > target:
# Target está à esquerda
high = mid - 1
else:
# Target está à direita
low = mid + 1

# Target não encontrado
return -1
41 changes: 36 additions & 5 deletions algorithms_project/algorithms/arrays/len_last_word.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,52 @@
"""
Este código implementa duas soluções diferentes para o problema
"Length of Last Word" (LeetCode 58).

Objetivo:
Dada uma string que contém palavras e espaços, retornar o comprimento
da última palavra (sequência de caracteres não vazios separados por espaços).

A classe Solution resolve o problema manualmente usando ponteiros (left e right).
A classe Solution2 resolve de forma mais simples usando o método split() do Python.
"""


class Solution():
def lengthOfLastWord(self, string_word: str) -> int:
"""
:type s: str
:rtype: int
"""
left, right = 0, 0
# Incializa os poneiros left e right em 0
left, right = 0, 0
# Lista para armazenar as palavras encontradas
words = []

# Loop percorre a string até o final
while right < len(string_word):
# Se o caractere atual não for espaço, move o ponteiro da direita
if string_word[right] != ' ':
right += 1
right += 1
else:
# Caso encontre espaço, adiciona a palavra entre left e right
words.append(string_word[left:right])
# Avança o ponteiro right para pular o espaço
right += 1
# Atualiza o ponteiro left para o próximo inicio de palavra
left = right
# após o loop, adiciona a ultima palavra capturada
words.append(string_word[left:right])

# Retorna o tamanho da última palavra capturada
return len(words[-1])


class Solution2():
def lengthOfLastWord(self, string_word: str) -> int:
"""
:type s: str
:rtype: int
"""
# Usa split() para separar a string em palavras igorando múltiplos espaços
words = string_word.split()
# Retorna o comprimento da última palavra
return len(words[-1])

20 changes: 20 additions & 0 deletions algorithms_project/tests/test_arrays/test_exponential_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import pytest
from algorithms_project.algorithms.arrays.exponential_search import Solution, ArrayReader


@pytest.mark.parametrize("array,target,expected", [
([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], 14, 13),
])
def test_exponential_search(array, target, expected):
assert Solution().exponencial_search(array, target) == expected

@pytest.mark.parametrize("array,target,expected", [
([-1, 0, 3, 5, 9, 12], 9, 4),
([-1, 0, 3, 5, 9, 12], 2, -1),
])
def test_exponential_search_unknown_size(array, target, expected):
reader = ArrayReader(array)
assert Solution().exponencial_search(array, target) == expected
9 changes: 8 additions & 1 deletion algorithms_project/tests/test_arrays/test_len_last_word.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import pytest
from algorithms.arrays.len_last_word import Solution
from algorithms.arrays.len_last_word import Solution, Solution2


@pytest.mark.parametrize("string_word,expected", [
("Hello World", 5),
])
def test_lengthOfLastWord(string_word, expected):
assert Solution().lengthOfLastWord(string_word) == expected


@pytest.mark.parametrize("string_word,expected", [
("Hello World", 5),
])
def test_lengthOfLastWord1(string_word, expected):
assert Solution2().lengthOfLastWord(string_word) == expected
Loading