diff --git a/DIRECTORY.md b/DIRECTORY.md index ed9e203..6045aa6 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -9,6 +9,7 @@ * [Get Products Of All Other Elements](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/get_products_of_all_other_elements.rb) * [Sort Squares Of An Array](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/sort_squares_of_an_array.rb) * [Two Sum](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/two_sum.rb) + * [Two Sum Ii](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/arrays/two_sum_ii.rb) * Binary Trees * [Inorder Traversal](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/binary_trees/inorder_traversal.rb) * [Invert](https://github.com/TheAlgorithms/Ruby/blob/master/data_structures/binary_trees/invert.rb) diff --git a/data_structures/arrays/sort_squares_of_an_array.rb b/data_structures/arrays/sort_squares_of_an_array.rb index 820f6e6..717fdb3 100644 --- a/data_structures/arrays/sort_squares_of_an_array.rb +++ b/data_structures/arrays/sort_squares_of_an_array.rb @@ -22,6 +22,7 @@ print(sorted_squares([4, -1, -9, 2])) def bubble_sort(array) array_length = array.size return array if array_length <= 1 + loop do swapped = false (array_length - 1).times do |i| diff --git a/data_structures/arrays/two_sum.rb b/data_structures/arrays/two_sum.rb index 318ee7f..b872625 100644 --- a/data_structures/arrays/two_sum.rb +++ b/data_structures/arrays/two_sum.rb @@ -1,4 +1,5 @@ # Challenge name: Two Sum +# # Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target. # # You may assume that each input would have exactly one solution, and you may not use the same element twice. @@ -23,44 +24,52 @@ # @param {Integer} target # @return {Integer[]} -# +# # Approach 1: Brute Force with Addition # + +# Complexity analysis + # Time Complexity: O(n^2). For each element, we try to find its complement # by looping through the rest of the array which takes O(n) time. # Therefore, the time complexity is O(n^2) + # Space complexity: O(1) -# + def two_sum(nums, target) result_array = [] - nums.each_with_index do |num, i| - nums.each_with_index do |num, j| - if i != j && i < j - current_sum = nums[i] + nums[j] - if current_sum == target - return [i, j] - end - end + nums.count.times do |i| + nums.count.times do |j| + next unless i != j && i < j + + current_sum = nums[i] + nums[j] + + return [i, j] if current_sum == target end end end -print two_sum([2, 7, 11, 15], 9) +print(two_sum([2, 7, 11, 15], 9)) # => [0,1] -print two_sum([3, 2, 4], 6) + +print(two_sum([3, 2, 4], 6)) # => [1,2] -print two_sum([3, 3], 6) + +print(two_sum([3, 3], 6)) # => [0,1] # # Approach 2: Brute Force with Difference # +# Complexity analysis +# # Time Complexity: O(N^2), where N is the length of the array # def two_sum(nums, target) nums.each_with_index do |num, i| - target_difference = target - nums[i] + target_difference = target - num + nums.each_with_index do |num, j| if i != j && num == target_difference return [i, j] @@ -69,38 +78,56 @@ def two_sum(nums, target) end end -print two_sum([2, 7, 11, 15], 9) +print(two_sum([2, 7, 11, 15], 9)) # => [0,1] -print two_sum([3, 2, 4], 6) + +print(two_sum([3, 2, 4], 6)) # => [1,2] -print two_sum([3, 3], 6) + +print(two_sum([3, 3], 6)) # => [0,1] # # Approach 3: Using a Hash # + +# Complexity analysis + # Time complexity: O(n). We traverse the list containing n elements exactly twice. # Since the hash table reduces the lookup time to O(1), the time complexity is O(n). # Space complexity: O(n). The extra space required depends on the number of items # stored in the hash table, which stores exactly n elements. -# + def two_sum(nums, target) hash = {} + # create a hash to store values and their indices nums.each_with_index do |num, i| hash[num] = i end + # iterate over nums array to find the target (difference between sum target and num) nums.each_with_index do |num, i| difference_target = target - num - return [i, hash[difference_target]] if hash[difference_target] && hash[difference_target] != i + + if hash[difference_target] && hash[difference_target] != i + return [i, hash[difference_target]] + end end end -print two_sum([2, 7, 11, 15], 9) +nums = [2, 7, 11, 15] +target = 9 +print(two_sum(nums, target)) # => [0,1] -print two_sum([3, 2, 4], 6) + +nums = [3, 2, 4] +target = 6 +print(two_sum(nums, target)) # => [1,2] -print two_sum([3, 3], 6) + +nums = [3, 3] +target = 6 +print(two_sum(nums, target)) # => [0,1] diff --git a/data_structures/arrays/two_sum_ii.rb b/data_structures/arrays/two_sum_ii.rb new file mode 100644 index 0000000..6e390b8 --- /dev/null +++ b/data_structures/arrays/two_sum_ii.rb @@ -0,0 +1,49 @@ +# Given an array of integers numbers that is already sorted in ascending order, find two numbers such that they add up to a specific target number. + +# Return the indices of the two numbers (1-indexed) as an integer array answer of size 2, where 1 <= answer[0] < answer[1] <= numbers.length. + +# You may assume that each input would have exactly one solution and you may not use the same element twice. + +# +# Approach 1: Two pointers +# + +# Complexity analysis + +# Time complexity: O(n). Each of the n elements is visited at +# most once, thus the time complexity is O(n). + +# Space complexity: O(1). We only use two indexes, the space +# complexity is O(1). + +def two_sum(numbers, target) + i = 0 + j = numbers.length - 1 + + while i < j + sum = numbers[i] + numbers[j] + + if target < sum + j -= 1 + elsif target > sum + i += 1 + else + return [i + 1, j + 1] + end + end +end + +nums = [2, 7, 11, 15] +target = 9 +print(two_sum(nums, target)) +# => [1,2] + +nums = [2, 3, 4] +target = 6 +print(two_sum(nums, target)) +# => [1,3] + +nums = [-1, 0] +target = -1 +print(two_sum(nums, target)) +# => [1,2]