diff --git a/data_structures/arrays/majority_element.py b/data_structures/arrays/majority_element.py new file mode 100644 index 000000000000..a03edfb198b2 --- /dev/null +++ b/data_structures/arrays/majority_element.py @@ -0,0 +1,37 @@ +""" +Find the majority element in an array. +""" + + +def majority_element(nums: list[int]) -> int: + """ + Find the element that appears more than n/2 times using + Boyer-Moore Voting Algorithm. + + Args: + nums: List of integers. + + Returns: + The majority element. + + Examples: + >>> majority_element([3, 2, 3]) + 3 + >>> majority_element([2, 2, 1, 1, 1, 2, 2]) + 2 + """ + count = 0 + candidate = None + + for num in nums: + if count == 0: + candidate = num + count += 1 if num == candidate else -1 + + return candidate + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/data_structures/arrays/maximum_subarray.py b/data_structures/arrays/maximum_subarray.py new file mode 100644 index 000000000000..a45a62e7e688 --- /dev/null +++ b/data_structures/arrays/maximum_subarray.py @@ -0,0 +1,36 @@ +""" +Find the maximum subarray sum (Kadane's Algorithm). +""" + + +def max_subarray(nums: list[int]) -> int: + """ + Find the contiguous subarray with the largest sum. + + Args: + nums: List of integers. + + Returns: + Maximum sum of subarray. + + Examples: + >>> max_subarray([-2,1,-3,4,-1,2,1,-5,4]) + 6 + >>> max_subarray([1]) + 1 + >>> max_subarray([5,4,-1,7,8]) + 23 + """ + max_sum = current_sum = nums[0] + + for num in nums[1:]: + current_sum = max(num, current_sum + num) + max_sum = max(max_sum, current_sum) + + return max_sum + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/data_structures/arrays/median_of_two_sorted_arrays.py b/data_structures/arrays/median_of_two_sorted_arrays.py new file mode 100644 index 000000000000..972b0ee44201 --- /dev/null +++ b/data_structures/arrays/median_of_two_sorted_arrays.py @@ -0,0 +1,61 @@ +""" +https://www.enjoyalgorithms.com/blog/median-of-two-sorted-arrays +""" + + +def find_median_sorted_arrays(nums1: list[int], nums2: list[int]) -> float: + """ + Find the median of two arrays. + + Args: + nums1: The first array. + nums2: The second array. + + Returns: + The median of the two arrays. + + Examples: + >>> find_median_sorted_arrays([1, 3], [2]) + 2.0 + + >>> find_median_sorted_arrays([1, 2], [3, 4]) + 2.5 + + >>> find_median_sorted_arrays([0, 0], [0, 0]) + 0.0 + + >>> find_median_sorted_arrays([], []) + Traceback (most recent call last): + ... + ValueError: Both input arrays are empty. + + >>> find_median_sorted_arrays([], [1]) + 1.0 + + >>> find_median_sorted_arrays([-1000], [1000]) + 0.0 + + >>> find_median_sorted_arrays([-1.1, -2.2], [-3.3, -4.4]) + -2.75 + """ + if not nums1 and not nums2: + raise ValueError("Both input arrays are empty.") + + # Merge the arrays into a single sorted array. + merged = sorted(nums1 + nums2) + total = len(merged) + + if total % 2 == 1: # If the total number of elements is odd + return float(merged[total // 2]) # then return the middle element + + # If the total number of elements is even, calculate + # the average of the two middle elements as the median. + middle1 = merged[total // 2 - 1] + middle2 = merged[total // 2] + return (float(middle1) + float(middle2)) / 2.0 + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/data_structures/arrays/rotate_array.py b/data_structures/arrays/rotate_array.py new file mode 100644 index 000000000000..a2951f8823e8 --- /dev/null +++ b/data_structures/arrays/rotate_array.py @@ -0,0 +1,33 @@ +""" +Rotate an array to the right by k steps. +""" + + +def rotate(nums: list[int], k: int) -> list[int]: + """ + Rotate the array to the right by k steps. + + Args: + nums: List of integers. + k: Number of steps to rotate. + + Returns: + The rotated list. + + Examples: + >>> rotate([1,2,3,4,5,6,7], 3) + [5, 6, 7, 1, 2, 3, 4] + + >>> rotate([-1,-100,3,99], 2) + [3, 99, -1, -100] + """ + n = len(nums) + k = k % n # In case k > n + nums[:] = nums[-k:] + nums[:-k] + return nums + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/data_structures/hashing/number_theory/median_of_two_sorted_arrays.py b/data_structures/hashing/number_theory/median_of_two_sorted_arrays.py new file mode 100644 index 000000000000..972b0ee44201 --- /dev/null +++ b/data_structures/hashing/number_theory/median_of_two_sorted_arrays.py @@ -0,0 +1,61 @@ +""" +https://www.enjoyalgorithms.com/blog/median-of-two-sorted-arrays +""" + + +def find_median_sorted_arrays(nums1: list[int], nums2: list[int]) -> float: + """ + Find the median of two arrays. + + Args: + nums1: The first array. + nums2: The second array. + + Returns: + The median of the two arrays. + + Examples: + >>> find_median_sorted_arrays([1, 3], [2]) + 2.0 + + >>> find_median_sorted_arrays([1, 2], [3, 4]) + 2.5 + + >>> find_median_sorted_arrays([0, 0], [0, 0]) + 0.0 + + >>> find_median_sorted_arrays([], []) + Traceback (most recent call last): + ... + ValueError: Both input arrays are empty. + + >>> find_median_sorted_arrays([], [1]) + 1.0 + + >>> find_median_sorted_arrays([-1000], [1000]) + 0.0 + + >>> find_median_sorted_arrays([-1.1, -2.2], [-3.3, -4.4]) + -2.75 + """ + if not nums1 and not nums2: + raise ValueError("Both input arrays are empty.") + + # Merge the arrays into a single sorted array. + merged = sorted(nums1 + nums2) + total = len(merged) + + if total % 2 == 1: # If the total number of elements is odd + return float(merged[total // 2]) # then return the middle element + + # If the total number of elements is even, calculate + # the average of the two middle elements as the median. + middle1 = merged[total // 2 - 1] + middle2 = merged[total // 2] + return (float(middle1) + float(middle2)) / 2.0 + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/data_structures/linked_list/reverse_linked_list.py b/data_structures/linked_list/reverse_linked_list.py new file mode 100644 index 000000000000..4b78f9969b7e --- /dev/null +++ b/data_structures/linked_list/reverse_linked_list.py @@ -0,0 +1,58 @@ +""" +https://www.enjoyalgorithms.com/blog/reverse-linked-list +""" + + +class ListNode: + """Definition for singly-linked list.""" + + def __init__(self, val=0, next=None): + self.val = val + self.next = next + + +def reverse_linked_list(head: ListNode) -> ListNode: + """ + Reverse a singly linked list. + + Args: + head: The head node of the linked list. + + Returns: + The new head node of the reversed linked list. + + Examples: + >>> a = ListNode(1) + >>> b = ListNode(2) + >>> c = ListNode(3) + >>> a.next, b.next = b, c + >>> head = reverse_linked_list(a) + >>> [head.val, head.next.val, head.next.next.val] + [3, 2, 1] + """ + prev = None + current = head + while current: + nxt = current.next + current.next = prev + prev = current + current = nxt + return prev + + +if __name__ == "__main__": + import doctest + + doctest.testmod() + + # Example execution + a = ListNode(1) + b = ListNode(2) + c = ListNode(3) + a.next, b.next = b, c + + print("Original Linked List: 1 -> 2 -> 3") + new_head = reverse_linked_list(a) + print( + f"Reversed Linked List: {new_head.val} -> {new_head.next.val} -> {new_head.next.next.val}" + )