diff --git a/algorithms_project/algorithms/arrays/binary_search.py b/algorithms_project/algorithms/arrays/binary_search.py index e37fa3d..c5a9086 100644 --- a/algorithms_project/algorithms/arrays/binary_search.py +++ b/algorithms_project/algorithms/arrays/binary_search.py @@ -1,30 +1,26 @@ class Binary: - def binary_search(nums, n): - low = 0 - high = len(nums) - steps = 0 + @staticmethod + def binary_search(nums, target): + """ + Perform a binary search on a sorted list / Realiza uma busca binária em uma lista ordenada. + Args: + nums (list): A sorted list of numbers / Uma lista ordenada de números + target (int): The value to search for / O valor a ser procurado + Returns: + int: Steps to find target, or -1 if not found / Passos para encontrar o alvo, ou -1 se não encontrado + """ - while low < high: - steps += 1 - mid = int((low + high)/2) + low = 0 # Starting index / Índice inicial + high = len(nums) - 1 # Ending index / Índice final + steps = 0 # Step counter / Contador de passos - if nums[mid] == n: - print("step: ", steps) - return mid - elif nums[mid] < n: - low = mid+1 - else: - high = mid - return -1 - - -a = [1, 2, 3, 4, 5] -b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] -c = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] -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] - -binary = Binary -binary.binary_search(a, 3) -binary.binary_search(b, 3) -binary.binary_search(c, 3) -binary.binary_search(d, 3) + while low <= high: # While range is valid / Enquanto o intervalo for válido + steps += 1 # Count step / Conta o passo + mid = (low + high) // 2 # Middle index / Índice do meio + if nums[mid] == target: # Target found / Alvo encontrado + return steps # Return steps / Retorna passos + elif nums[mid] < target: # Middle smaller than target / Meio menor que alvo + low = mid + 1 # Search right / Busca à direita + else: # Middle larger than target / Meio maior que alvo + high = mid - 1 # Search left / Busca à esquerda + return -1 # Target not found / Alvo não encontrado diff --git a/algorithms_project/algorithms/arrays/len_last_word.py b/algorithms_project/algorithms/arrays/len_last_word.py new file mode 100644 index 0000000..3d9213a --- /dev/null +++ b/algorithms_project/algorithms/arrays/len_last_word.py @@ -0,0 +1,21 @@ +class Solution(): + def lengthOfLastWord(self, string_word: str) -> int: + """ + :type s: str + :rtype: int + """ + left, right = 0, 0 + words = [] + + while right < len(string_word): + if string_word[right] != ' ': + right += 1 + else: + words.append(string_word[left:right]) + right += 1 + left = right + + words.append(string_word[left:right]) + + return len(words[-1]) + diff --git a/algorithms_project/algorithms/arrays/two_pointer.py b/algorithms_project/algorithms/arrays/two_pointer.py index a124a37..8aa104a 100644 --- a/algorithms_project/algorithms/arrays/two_pointer.py +++ b/algorithms_project/algorithms/arrays/two_pointer.py @@ -1,19 +1,19 @@ class Solution: def reverseWords_manual(string_word): - res = '' - left, right = 0, 0 - - while right < len(string_word): - if string_word[right] != ' ': - right += 1 - else: - res += string_word[left:right+1][::-1] - right += 1 + res = '' # Para realizar o reverse da string cria-se uma substring + left, right = 0, 0 # Inici-ase os ponteiros left e right em zero + + while right < len(string_word): # loop dentro do tamanho da string + if string_word[right] != ' ': # enquanto a posição de right dentro da string for diferente de espaço em branco + right += 1 # incrementa o right para continuar o loop + else: # caso encontre um espaço vazio + res += string_word[left:right+1][::-1] # sera adicionado os valores na substring dos ponteiros left e right invertidos [::-1] + right += 1 # incrementa +1 no right para sair do espaço vazio e iniciar a leitura da proxima palavra left = right - res += ' ' - res += string_word[left:right + 2][::-1] - return res[1:] + res += ' ' # pula um espaço na substring para acrescentar a proxima palavra + res += string_word[left:right + 2][::-1] # adicina a proxima palavra na substring acrescenta o 2porque saiu fora do loop acima e reverte + return res[1:] # começa da posição 1 devido ter um espaço em branco no começo cat = Solution.reverseWords_manual("rac tar") @@ -22,7 +22,7 @@ def reverseWords_manual(string_word): class Solution2: def reverserWords(s): - return ' '.join(word[::-1] for word in s.split()) + return ' '.join(word[::-1] for word in s.split()) # utilizando modulo pronto da linguagem para resolver reverseword = Solution2.reverserWords("I evol edocteel") @@ -34,11 +34,16 @@ def reverseWords_manual1(sword: str) -> str: res = '' left = 0 for right in range(len(sword) + 1): + # Percorre todos os índices da string + 1 (para capturar o último "fim de palavra") if right == len(sword) or sword[right] == ' ': + # Se chegamos no final da string OU encontramos um espaço (fim de palavra): res += sword[left:right][::-1] + # Pega a palavra entre left e right, inverte ( [::-1] ) e adiciona ao resultado if right < len(sword): res += ' ' + # Se não for o último caractere, adiciona um espaço ao resultado left = right + 1 + # Move o ponteiro 'left' para o início da próxima palavra return res diff --git a/algorithms_project/algorithms/sliding_window/sliding_window.py b/algorithms_project/algorithms/sliding_window/sliding_window.py new file mode 100644 index 0000000..1b21087 --- /dev/null +++ b/algorithms_project/algorithms/sliding_window/sliding_window.py @@ -0,0 +1,35 @@ +class Solution: + def maximumLengthSubstring(self, string_word: str) -> int: + """ + Find the maximum length substring where no character appears more than twice + / Encontra o comprimento máximo de uma substring onde nenhum caractere aparece mais de duas vezes. + + Args: + string_word (str): The input string to analyze + / A string de entrada para analisar. + + Returns: + int: The length of the longest valid substring + / O comprimento da substring válida mais longa. + """ + + left, right = 0, 0 # Initialize window pointers / Inicializa os ponteiros da janela + _max = 1 # Maximum length found / Maior comprimento encontrado + counter = {} # Dictionary to count characters / Dicionário para contar caracteres + + counter[string_word[0]] = 1 # Count first character / Conta o primeiro caractere + while right < len(string_word) - 1: # While right pointer is within string / Enquanto o ponteiro direito estiver dentro da string + right += 1 # Move right pointer / Move o ponteiro direito + + if counter.get(string_word[right]): # If character already in counter / Se o caractere já está no contador + counter[string_word[right]] += 1 # Increment its count / Incrementa a contagem + else: + counter[string_word[right]] = 1 # Otherwise initialize count / Caso contrário, inicializa a contagem + + while counter[string_word[right]] == 3: # While character appears 3 times / Enquanto o caractere aparecer 3 vezes + counter[string_word[left]] -= 1 # Decrease count of leftmost char / Diminui a contagem do caractere mais à esquerda + left += 1 # Move left pointer / Move o ponteiro esquerdo + + _max = max(_max, right - left + 1) # Update maximum length / Atualiza o comprimento máximo + + return _max # Return maximum length / Retorna o comprimento máximo diff --git a/algorithms_project/algorithms/sliding_window/solution.py b/algorithms_project/algorithms/sliding_window/solution.py deleted file mode 100644 index 6c3d001..0000000 --- a/algorithms_project/algorithms/sliding_window/solution.py +++ /dev/null @@ -1,27 +0,0 @@ -class Solution: - def maximumLengthSubstring(self, s: str) -> int: - left, right = 0, 0 - _max = 1 - counter = {} - - counter[s[0]] = 1 - - while right < len(s) - 1: - right += 1 - if counter.get(s[right]): - counter[s[right]] += 1 - else: - counter[s[right]] = 1 - - while counter[s[right]] == 3: - counter[s[left]] -= 1 - left += 1 - _max = max(_max, right - left + 1) - return _max - - -solution = Solution -s = "bcbbbcbaaaaaaabcbdaaddddacbbbbb" -result = solution.maximumLengthSubstring(3, s) - -print(f'Maximum length of substring with 3 a\'s is {result}') # Output: 2 diff --git a/algorithms_project/tests/test_arrays/test_len_last_word.py b/algorithms_project/tests/test_arrays/test_len_last_word.py new file mode 100644 index 0000000..2e97716 --- /dev/null +++ b/algorithms_project/tests/test_arrays/test_len_last_word.py @@ -0,0 +1,9 @@ +import pytest +from algorithms.arrays.len_last_word import Solution + + +@pytest.mark.parametrize("string_word,expected", [ + ("Hello World", 5), +]) +def test_lengthOfLastWord(string_word, expected): + assert Solution().lengthOfLastWord(string_word) == expected diff --git a/algorithms_project/tests/test_arrays/test_two_pointer.py b/algorithms_project/tests/test_arrays/test_two_pointer.py index 45c5cdb..b76ab77 100644 --- a/algorithms_project/tests/test_arrays/test_two_pointer.py +++ b/algorithms_project/tests/test_arrays/test_two_pointer.py @@ -17,8 +17,9 @@ def test_reverse_words(input_str, expected): def test_reverse_words1(input_str, expected): assert Solution2.reverserWords(input_str) == expected + @pytest.mark.parametrize("input_str,expected", [ ("Let's take LeetCode contest", "s'teL ekat edoCteeL tsetnoc"), ]) def test_reverse_words2(input_str, expected): - assert Solution3.reverseWords_manual1(input_str) == expected \ No newline at end of file + assert Solution3.reverseWords_manual1(input_str) == expected diff --git a/algorithms_project/tests/test_binary_search/test_binarysearch.py b/algorithms_project/tests/test_binary_search/test_binarysearch.py new file mode 100644 index 0000000..0930bcc --- /dev/null +++ b/algorithms_project/tests/test_binary_search/test_binarysearch.py @@ -0,0 +1,12 @@ +import pytest +from algorithms.arrays.binary_search import Binary + + +@pytest.mark.parametrize("array,target,expected", [ + ([1, 2, 3, 4, 5], 3, 1), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3, 3), + ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], 3, 4), + ([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], 3, 5) +]) +def test_binary_search(array, target, expected): + assert Binary.binary_search(array, target) == expected diff --git a/algorithms_project/tests/test_sliding_window/test_sliding_window.py b/algorithms_project/tests/test_sliding_window/test_sliding_window.py new file mode 100644 index 0000000..4aa97b0 --- /dev/null +++ b/algorithms_project/tests/test_sliding_window/test_sliding_window.py @@ -0,0 +1,9 @@ +import pytest +from algorithms.sliding_window.sliding_window import Solution + + +@pytest.mark.parametrize("max,string,expected ", [ + (3, "bcbbbcbaaaaaaabcbdaaddddacbbbbb", 7), +]) +def test_binary_search(max, string, expected): + assert Solution.maximumLengthSubstring(max, string) == expected diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..0beea5e --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[tool.pytest.ini_options] +python_files = "test_*.py" +testpaths = ["tests"] diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index dbeb499..0000000 --- a/pytest.ini +++ /dev/null @@ -1,4 +0,0 @@ -# -- FILE: pytest.ini (or tox.ini) -[pytest] -python_files = test_*.py -pythonpath = algorithms_project \ No newline at end of file