From e676e283eaf7170d38f802d12b982a7129598989 Mon Sep 17 00:00:00 2001 From: sidaksohi <31377210+sidaksohi@users.noreply.github.com> Date: Sun, 22 Aug 2021 15:45:08 -0700 Subject: [PATCH 1/6] Add array solutions with descriptions --- data_structures/arrays/3sum.rb | 80 +++++++++++++++++++ .../arrays/maximum_product_subarray.rb | 44 ++++++++++ data_structures/arrays/maximum_subarray.rb | 56 +++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 data_structures/arrays/3sum.rb create mode 100644 data_structures/arrays/maximum_product_subarray.rb create mode 100644 data_structures/arrays/maximum_subarray.rb diff --git a/data_structures/arrays/3sum.rb b/data_structures/arrays/3sum.rb new file mode 100644 index 0000000..1e4bf80 --- /dev/null +++ b/data_structures/arrays/3sum.rb @@ -0,0 +1,80 @@ +#Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] .. +#.. such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0. +#Notice that the solution set must not contain duplicate triplets. + +#Example 1: +#Input: nums = [-1,0,1,2,-1,-4] +#Output: [[-1,-1,2],[-1,0,1]] + +#Example 2: +#Input: nums = [] +#Output: [] + +#Example 3: +#Input: nums = [0] +#Output: [] + +#Constraints: +#0 <= nums.length <= 3000 +#-105 <= nums[i] <= 105 + + + + +#Two Pointer Approach - O(n) Time / O(1) Space +#Return edge cases. +#Sort nums, and init ans array +#For each |val, index| in nums: +#if the current value is the same as last, then go to next iteration +#init left and right pointers for two pointer search of the two sum in remaining elements of array +#while left < right: +#find current sum +#if sum > 0, right -= 1 +#if sum < 0, left += 1 +#if it's 0, then add the values to the answer array, and set the left pointer to the next valid value .. +#.. (left += 1 while nums[left] == nums[left - 1] && left < right) +#Return ans[] + + +# @param {Integer[]} nums +# @return {Integer[][]} +def three_sum(nums) + #return if length too short + return [] if nums.length < 3 + + #sort nums, init ans array + nums, ans = nums.sort, [] + + #loop through nums + nums.each_with_index do |val, ind| + #if the previous value is the same as current, then skip this iteration as it would create duplicates + next if ind > 0 && nums[ind] == nums[ind - 1] + + #init & run two pointer search + left, right = ind + 1, nums.length - 1 + + while left < right + #find current sum + sum = val + nums[left] + nums[right] + + #decrease sum if it's too great, increase sum if it's too low + if sum > 0 + right -= 1 + elsif sum < 0 + left += 1 + #if it's zero, then add the answer to array and set left pointer to next valid value + else + ans << [val, nums[left], nums[right]] + + left += 1 + + while nums[left] == nums[left - 1] && left < right + left += 1 + end + end + end + end + + #return answer + ans +end \ No newline at end of file diff --git a/data_structures/arrays/maximum_product_subarray.rb b/data_structures/arrays/maximum_product_subarray.rb new file mode 100644 index 0000000..da458bc --- /dev/null +++ b/data_structures/arrays/maximum_product_subarray.rb @@ -0,0 +1,44 @@ +#Given an integer array nums, find a contiguous non-empty subarray within the array that has the largest product, and return the product. +#It is guaranteed that the answer will fit in a 32-bit integer. +#A subarray is a contiguous subsequence of the array. + +#Example 1: +#Input: nums = [2,3,-2,4] +#Output: 6 +#Explanation: [2,3] has the largest product 6. + +#Example 2: +#Input: nums = [-2,0,-1] +#Output: 0 +#Explanation: The result cannot be 2, because [-2,-1] is not a subarray. + +#Constraints: +#1 <= nums.length <= 2 * 104 +#-10 <= nums[i] <= 10 +#The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer. + + + + +#Dynamic Programming Approach (Kadane's Algorithm) - O(n) Time / O(1) Space +#Track both current minimum and current maximum (Due to possibility of multiple negative numbers) +#Answer is the highest value of current maximum + + +# @param {Integer[]} nums +# @return {Integer} +def max_product(nums) + return nums[0] if nums.length == 1 + + cur_min, cur_max, max = 1, 1, -11 + + nums.each do |val| + tmp_cur_max = cur_max + cur_max = [val, val*cur_max, val*cur_min].max + cur_min = [val, val*tmp_cur_max, val*cur_min].min + + max = [max, cur_max].max + end + + max +end \ No newline at end of file diff --git a/data_structures/arrays/maximum_subarray.rb b/data_structures/arrays/maximum_subarray.rb new file mode 100644 index 0000000..5c85167 --- /dev/null +++ b/data_structures/arrays/maximum_subarray.rb @@ -0,0 +1,56 @@ +#Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum. +#A subarray is a contiguous part of an array. + +#Example 1: +#Input: nums = [-2,1,-3,4,-1,2,1,-5,4] +#Output: 6 +#Explanation: [4,-1,2,1] has the largest sum = 6. + +#Example 2: +#Input: nums = [1] +#Output: 1 + +#Example 3: +#Input: nums = [5,4,-1,7,8] +#Output: 23 + +#Constraints: +#1 <= nums.length <= 3 * 104 +#-105 <= nums[i] <= 105 + + + + +#Sliding Window Approach - O(n) Time / O(1) Space +#Init max_sum as first element +#Return first element if the array length is 1 +#Init current_sum as 0 +#Iterate through the array: +#if current_sum < 0, then reset it to 0 (to eliminate any negative prefixes) +#current_sum += num +#max_sum = current_sum if current_sum is greater than max_sum +#Return max_sum + + +# @param {Integer[]} nums +# @return {Integer} +def max_sub_array(nums) + #initialize max sum to first number + max_sum = nums[0] + + #return first number if array length is 1 + return max_sum if nums.length == 1 + + #init current sum to 0 + current_sum = 0 + + #iterate through array, reset current_sum to 0 if it ever goes below 0, track max_sum with highest current_sum + nums.each do |num| + current_sum = 0 if current_sum < 0 + current_sum += num + max_sum = [max_sum, current_sum].max + end + + #return answer + max_sum +end \ No newline at end of file From 8519e419faa8e39f4ca969de387bd48f21ef412a Mon Sep 17 00:00:00 2001 From: sidaksohi <31377210+sidaksohi@users.noreply.github.com> Date: Wed, 25 Aug 2021 15:41:20 -0700 Subject: [PATCH 2/6] Update maximum_subarray.rb --- data_structures/arrays/maximum_subarray.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data_structures/arrays/maximum_subarray.rb b/data_structures/arrays/maximum_subarray.rb index 5c85167..ad2059e 100644 --- a/data_structures/arrays/maximum_subarray.rb +++ b/data_structures/arrays/maximum_subarray.rb @@ -21,7 +21,7 @@ -#Sliding Window Approach - O(n) Time / O(1) Space +#Dynamic Programming Approach (Kadane's Algorithm) - O(n) Time / O(1) Space #Init max_sum as first element #Return first element if the array length is 1 #Init current_sum as 0 @@ -29,7 +29,7 @@ #if current_sum < 0, then reset it to 0 (to eliminate any negative prefixes) #current_sum += num #max_sum = current_sum if current_sum is greater than max_sum -#Return max_sum +#Return max_sum # @param {Integer[]} nums @@ -53,4 +53,4 @@ def max_sub_array(nums) #return answer max_sum -end \ No newline at end of file +end From bd92198fc8c729cb3deeb0b22c4345ff2b4959a0 Mon Sep 17 00:00:00 2001 From: Vitor Oliveira Date: Fri, 3 Sep 2021 12:33:56 -0700 Subject: [PATCH 3/6] add formatting and example outputs for quick debugging --- data_structures/arrays/3sum.rb | 144 +++++++++++++++++---------------- 1 file changed, 76 insertions(+), 68 deletions(-) diff --git a/data_structures/arrays/3sum.rb b/data_structures/arrays/3sum.rb index 1e4bf80..51801f2 100644 --- a/data_structures/arrays/3sum.rb +++ b/data_structures/arrays/3sum.rb @@ -1,80 +1,88 @@ -#Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] .. -#.. such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0. -#Notice that the solution set must not contain duplicate triplets. +# Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] .. +# .. such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0. +# Notice that the solution set must not contain duplicate triplets. -#Example 1: -#Input: nums = [-1,0,1,2,-1,-4] -#Output: [[-1,-1,2],[-1,0,1]] +# Example 1: +# Input: nums = [-1,0,1,2,-1,-4] +# Output: [[-1,-1,2],[-1,0,1]] -#Example 2: -#Input: nums = [] -#Output: [] +# Example 2: +# Input: nums = [] +# Output: [] -#Example 3: -#Input: nums = [0] -#Output: [] +# Example 3: +# Input: nums = [0] +# Output: [] -#Constraints: -#0 <= nums.length <= 3000 +# Constraints: +# 0 <= nums.length <= 3000 #-105 <= nums[i] <= 105 - - - -#Two Pointer Approach - O(n) Time / O(1) Space -#Return edge cases. -#Sort nums, and init ans array -#For each |val, index| in nums: -#if the current value is the same as last, then go to next iteration -#init left and right pointers for two pointer search of the two sum in remaining elements of array -#while left < right: -#find current sum -#if sum > 0, right -= 1 -#if sum < 0, left += 1 -#if it's 0, then add the values to the answer array, and set the left pointer to the next valid value .. -#.. (left += 1 while nums[left] == nums[left - 1] && left < right) -#Return ans[] - +# Two Pointer Approach - O(n) Time / O(1) Space +# Return edge cases. +# Sort nums, and init ans array +# For each |val, index| in nums: +# if the current value is the same as last, then go to next iteration +# init left and right pointers for two pointer search of the two sum in remaining elements of array +# while left < right: +# find current sum +# if sum > 0, right -= 1 +# if sum < 0, left += 1 +# if it's 0, then add the values to the answer array, and set the left pointer to the next valid value .. +# .. (left += 1 while nums[left] == nums[left - 1] && left < right) +# Return ans[] # @param {Integer[]} nums # @return {Integer[][]} def three_sum(nums) - #return if length too short - return [] if nums.length < 3 - - #sort nums, init ans array - nums, ans = nums.sort, [] - - #loop through nums - nums.each_with_index do |val, ind| - #if the previous value is the same as current, then skip this iteration as it would create duplicates - next if ind > 0 && nums[ind] == nums[ind - 1] - - #init & run two pointer search - left, right = ind + 1, nums.length - 1 - - while left < right - #find current sum - sum = val + nums[left] + nums[right] - - #decrease sum if it's too great, increase sum if it's too low - if sum > 0 - right -= 1 - elsif sum < 0 - left += 1 - #if it's zero, then add the answer to array and set left pointer to next valid value - else - ans << [val, nums[left], nums[right]] - - left += 1 - - while nums[left] == nums[left - 1] && left < right - left += 1 - end - end + # return if length too short + return [] if nums.length < 3 + + # sort nums, init ans array + nums = nums.sort + ans = [] + + # loop through nums + nums.each_with_index do |val, ind| + # if the previous value is the same as current, then skip this iteration as it would create duplicates + next if ind > 0 && nums[ind] == nums[ind - 1] + + # init & run two pointer search + left = ind + 1 + right = nums.length - 1 + + while left < right + # find current sum + sum = val + nums[left] + nums[right] + + # decrease sum if it's too great, increase sum if it's too low + if sum > 0 + right -= 1 + elsif sum < 0 + left += 1 + # if it's zero, then add the answer to array and set left pointer to next valid value + else + ans << [val, nums[left], nums[right]] + + left += 1 + + left += 1 while nums[left] == nums[left - 1] && left < right end end - - #return answer - ans -end \ No newline at end of file + end + + # return answer + ans +end + +nums = [-1, 0, 1, 2, -1, -4] +print three_sum(nums) +# Output: [[-1,-1,2],[-1,0,1]] + +nums = [] +print three_sum(nums) +# Output: [] + +nums = [0] +print three_sum(nums) +# Output: [] From b7d623a303db07ea78aa9c82ca08e8210720ef55 Mon Sep 17 00:00:00 2001 From: Vitor Oliveira Date: Fri, 3 Sep 2021 12:35:10 -0700 Subject: [PATCH 4/6] add output for max_product algorithm --- .../arrays/maximum_product_subarray.rb | 77 ++++++++++--------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/data_structures/arrays/maximum_product_subarray.rb b/data_structures/arrays/maximum_product_subarray.rb index da458bc..37d97d2 100644 --- a/data_structures/arrays/maximum_product_subarray.rb +++ b/data_structures/arrays/maximum_product_subarray.rb @@ -1,44 +1,51 @@ -#Given an integer array nums, find a contiguous non-empty subarray within the array that has the largest product, and return the product. -#It is guaranteed that the answer will fit in a 32-bit integer. -#A subarray is a contiguous subsequence of the array. -#Example 1: -#Input: nums = [2,3,-2,4] -#Output: 6 -#Explanation: [2,3] has the largest product 6. +# Given an integer array nums, find a contiguous non-empty subarray within the array that has the largest product, and return the product. +# It is guaranteed that the answer will fit in a 32-bit integer. +# A subarray is a contiguous subsequence of the array. -#Example 2: -#Input: nums = [-2,0,-1] -#Output: 0 -#Explanation: The result cannot be 2, because [-2,-1] is not a subarray. +# Example 1: +# Input: nums = [2,3,-2,4] +# Output: 6 +# Explanation: [2,3] has the largest product 6. -#Constraints: -#1 <= nums.length <= 2 * 104 +# Example 2: +# Input: nums = [-2,0,-1] +# Output: 0 +# Explanation: The result cannot be 2, because [-2,-1] is not a subarray. + +# Constraints: +# 1 <= nums.length <= 2 * 104 #-10 <= nums[i] <= 10 -#The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer. - - - - -#Dynamic Programming Approach (Kadane's Algorithm) - O(n) Time / O(1) Space -#Track both current minimum and current maximum (Due to possibility of multiple negative numbers) -#Answer is the highest value of current maximum +# The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer. +# Dynamic Programming Approach (Kadane's Algorithm) - O(n) Time / O(1) Space +# Track both current minimum and current maximum (Due to possibility of multiple negative numbers) +# Answer is the highest value of current maximum # @param {Integer[]} nums # @return {Integer} def max_product(nums) - return nums[0] if nums.length == 1 - - cur_min, cur_max, max = 1, 1, -11 - - nums.each do |val| - tmp_cur_max = cur_max - cur_max = [val, val*cur_max, val*cur_min].max - cur_min = [val, val*tmp_cur_max, val*cur_min].min - - max = [max, cur_max].max - end - - max -end \ No newline at end of file + return nums[0] if nums.length == 1 + + cur_min = 1 + cur_max = 1 + max = -11 + + nums.each do |val| + tmp_cur_max = cur_max + cur_max = [val, val * cur_max, val * cur_min].max + cur_min = [val, val * tmp_cur_max, val * cur_min].min + + max = [max, cur_max].max + end + + max +end + +nums = [2, 3, -2, 4] +puts max_product(nums) +# Output: 6 + +nums = [-2, 0, -1] +puts max_product(nums) +# Output: 0 From aecd3739f0ed62dd3a457dde228a77b7e1ec0e22 Mon Sep 17 00:00:00 2001 From: Vitor Oliveira Date: Fri, 3 Sep 2021 12:37:05 -0700 Subject: [PATCH 5/6] add output for max_sub_array algorithm --- data_structures/arrays/maximum_subarray.rb | 102 +++++++++++---------- 1 file changed, 56 insertions(+), 46 deletions(-) diff --git a/data_structures/arrays/maximum_subarray.rb b/data_structures/arrays/maximum_subarray.rb index ad2059e..b1f7164 100644 --- a/data_structures/arrays/maximum_subarray.rb +++ b/data_structures/arrays/maximum_subarray.rb @@ -1,56 +1,66 @@ -#Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum. -#A subarray is a contiguous part of an array. +# Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum. +# A subarray is a contiguous part of an array. -#Example 1: -#Input: nums = [-2,1,-3,4,-1,2,1,-5,4] -#Output: 6 -#Explanation: [4,-1,2,1] has the largest sum = 6. +# Example 1: +# Input: nums = [-2,1,-3,4,-1,2,1,-5,4] +# Output: 6 +# Explanation: [4,-1,2,1] has the largest sum = 6. -#Example 2: -#Input: nums = [1] -#Output: 1 +# Example 2: +# Input: nums = [1] +# Output: 1 -#Example 3: -#Input: nums = [5,4,-1,7,8] -#Output: 23 +# Example 3: +# Input: nums = [5,4,-1,7,8] +# Output: 23 -#Constraints: -#1 <= nums.length <= 3 * 104 -#-105 <= nums[i] <= 105 - - - - -#Dynamic Programming Approach (Kadane's Algorithm) - O(n) Time / O(1) Space -#Init max_sum as first element -#Return first element if the array length is 1 -#Init current_sum as 0 -#Iterate through the array: -#if current_sum < 0, then reset it to 0 (to eliminate any negative prefixes) -#current_sum += num -#max_sum = current_sum if current_sum is greater than max_sum -#Return max_sum +# Constraints: +# 1 <= nums.length <= 3 * 104 +# -105 <= nums[i] <= 105 +# Dynamic Programming Approach (Kadane's Algorithm) - O(n) Time / O(1) Space +# +# Init max_sum as first element +# Return first element if the array length is 1 +# Init current_sum as 0 +# Iterate through the array: +# if current_sum < 0, then reset it to 0 (to eliminate any negative prefixes) +# current_sum += num +# max_sum = current_sum if current_sum is greater than max_sum +# Return max_sum # @param {Integer[]} nums # @return {Integer} def max_sub_array(nums) - #initialize max sum to first number - max_sum = nums[0] - - #return first number if array length is 1 - return max_sum if nums.length == 1 - - #init current sum to 0 - current_sum = 0 - - #iterate through array, reset current_sum to 0 if it ever goes below 0, track max_sum with highest current_sum - nums.each do |num| - current_sum = 0 if current_sum < 0 - current_sum += num - max_sum = [max_sum, current_sum].max - end - - #return answer - max_sum + # initialize max sum to first number + max_sum = nums[0] + + # return first number if array length is 1 + return max_sum if nums.length == 1 + + # init current sum to 0 + current_sum = 0 + + # iterate through array, reset current_sum to 0 if it ever goes below 0, track max_sum with highest current_sum + nums.each do |num| + current_sum = 0 if current_sum < 0 + + current_sum += num + + max_sum = [max_sum, current_sum].max + end + + max_sum end + +nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4] +print max_sub_array(nums) +# Output: 6 + +nums = [1] +print max_sub_array(nums) +# Output: 1 + +nums = [5, 4, -1, 7, 8] +print max_sub_array(nums) +# Output: 23 From f6382bfb15b9430af9f874d834bf222cbca5d322 Mon Sep 17 00:00:00 2001 From: Vitor Oliveira Date: Fri, 3 Sep 2021 12:37:45 -0700 Subject: [PATCH 6/6] kill space --- data_structures/arrays/maximum_product_subarray.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/data_structures/arrays/maximum_product_subarray.rb b/data_structures/arrays/maximum_product_subarray.rb index 37d97d2..2c5be6f 100644 --- a/data_structures/arrays/maximum_product_subarray.rb +++ b/data_structures/arrays/maximum_product_subarray.rb @@ -1,4 +1,3 @@ - # Given an integer array nums, find a contiguous non-empty subarray within the array that has the largest product, and return the product. # It is guaranteed that the answer will fit in a 32-bit integer. # A subarray is a contiguous subsequence of the array.