diff --git a/ContainersWithMostWater.java b/ContainersWithMostWater.java new file mode 100644 index 00000000..0a83dd1b --- /dev/null +++ b/ContainersWithMostWater.java @@ -0,0 +1,35 @@ +// Time Complexity : O(n), go through each value in height array to determine max area +// Space Complexity : O(1), no additional space +// Did this code successfully run on Leetcode : Yes +// Any problem you faced while coding this : No + +// Approach : +// Brute force - Do nested iteration, find the pair of heights, that have max area. +// Keep two pointer, one in the start and one in the end, calculate the area by +// the height x the width which is +// min(front, rear) x (rear-front). +// Whichever pointer has more height, keep it as it and move the other pointer. There is a chance we can find a pointer +// with much larger height, so the new area formed by existing pointer and pointer to new max height will have a larger area. +public class ContainersWithMostWater { + public int maxArea(int[] height) { + if(height.length == 0) return 0; + + int front = 0; + int rear = height.length -1; + int maxArea = 0; + while(front < rear){ + // Find the area, min(p1,p2) * width (p2-p1) + int area = Math.min(height[front], height[rear]) * (rear-front); + maxArea = Math.max(maxArea, area); + + // Move pointer with smaller height by 1 + if(height[front] < height[rear]){ + front += 1; + }else{ + rear -= 1; + } + + } + return maxArea; + } +} diff --git a/SortColors.java b/SortColors.java new file mode 100644 index 00000000..a5183acd --- /dev/null +++ b/SortColors.java @@ -0,0 +1,42 @@ +// Time Complexity : O(N), N - number of colors in the array +// Space Complexity : O(1) +// Did this code successfully run on Leetcode : Yes +// Any problem you faced while coding this : No + +// We can keep 3 pointers for 3 colors, blue-0, red-1, white-2 +// Red indicates the start of values that are unexplored +// Blue indicates the color are explored and the start of 0 +// White indicates the color are explored and is the start of 2. +// Whenever red encounters blue or white color we swap them with values in the front or the rear. +public class SortColors { + + public void sortColors(int[] nums) { + if(nums.length == 1) return; + int blue = 0; + int red = 0; + int white = nums.length-1; + + while(red <= white){ + // 2 Should be swapped to the rear and white pointer should decrease + if(nums[red] == 2){ + swap(red, white, nums); + white--; + }else if(nums[red] == 1){ + // If red, simply move on to next. If there are blues ahead, this red will be swapped with it. + red++; + }else{ + // 0 Should be swapped to the front and blue pointer should increase + swap(red, blue, nums); + blue++; + red++; + } + } + } + + public void swap(int i, int j, int[] nums){ + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } + +} diff --git a/ThreeSum.java b/ThreeSum.java new file mode 100644 index 00000000..5ea19011 --- /dev/null +++ b/ThreeSum.java @@ -0,0 +1,105 @@ +// Time Complexity : O(N^2) +// Space Complexity : O(1) +// Did this code successfully run on Leetcode : Yes +// Any problem you faced while coding this : No + +// Approach +// Brute force - nested iteration, find 3 pairs with 3 loops. O(N^3) time +// With unsorted array, using one hashset for keeping the triplets and another for doing O(1) search to find complement sum. +// We need to sort the triplets before adding to set. Keep 2 pointer p1 amd p2, find 3 values such that +// nums[p1] , nums[p2] , (0- (nums[p1]+nums[p2]) is in hashmap) - O(N^2 + nlogn) time, O(N) space + +// Using sorted array and 2 pointers approach, we keep 3 pointers and check if there sum is equal to 0. Move three pointers +// accordingly if we see any duplicates. +// O(N^2 + nlogn) = ~ O(N2) time, O(1) space + +import java.util.*; + +public class ThreeSum { + + public List> threeSum(int[] nums) { + // Time Complexity : O(N^2 + NlogN) = ~O(N^2) + // Space Complexity : O(1) + List> result = new ArrayList<>(); + int len = nums.length; + if (len == 3) { + if (nums[0] + nums[1] + nums[2] == 0) { + result.add(List.of(nums[0], nums[1], nums[2])); + } + return result; + } + + Arrays.sort(nums); + int index = 0; + while (index < len) { + if(nums[index] > 0){ + break; + } + if (index > 0 && nums[index] == nums[index - 1]) { + index++; + continue; + } + int first = index; + int second = index + 1; + int third = len - 1; + while (second < third) { + int currentSum = nums[first] + nums[second] + nums[third]; + if (currentSum == 0) { + result.add(List.of(nums[first], nums[second], nums[third])); + second++; + third--; + while (second < third && nums[second] == nums[second - 1]) { + second++; + } + while (second < third && nums[third] == nums[third + 1]) { + third--; + } + } else if (currentSum < 0) { + second++; + } else { + third--; + } + } + index++; + } + return result; + } + + public List> threeSumHashing(int[] nums) { + // Time Complexity : O(N^2), outer loop and inner loop to find all combination of triplets + constant(sorting 3 values) + // Space Complexity : O(N), + // Keep additional hashset to check if the 0-(nums1+nums2) exists in the input, so O(NXN) + // Keep temporary hashset with list of size 3, to avoid entering duplicate combinations in the final result. + int len = nums.length; + List> result = new ArrayList<>(); + if (len == 3) { + if (nums[0] + nums[1] + nums[2] == 0) { + result.add(List.of(nums[0], nums[1], nums[2])); + } + return result; + } + // Hashset to keep unique triplets and add them to final result list. Avoid duplicates in outer loop + HashSet> tempResult = new HashSet<>(); + for (int first = 0; first < len-1; first++) { + // Hashset to check if the complementary sum is present in the input, also to avoid inner duplicates + HashSet temp = new HashSet<>(); + for (int second = first + 1; second < len-2; second++) { + int currentSum = -(nums[first] + nums[second]); + if (temp.contains(currentSum)) { + addToResult(tempResult, nums[first], nums[second], currentSum); + } else { + temp.add(nums[second]); + } + } + } + result.addAll(tempResult); + return result; + } + + private void addToResult(HashSet> result, int first, int second, int third) { + List triplet = Arrays.asList(first,second,third); + Collections.sort(triplet); + result.add(triplet); + } + +}