From 86cccc252516b64efc67022175c2acdb23514c4b Mon Sep 17 00:00:00 2001 From: Harshitha Thondalapally Date: Mon, 12 Jan 2026 10:31:32 -0500 Subject: [PATCH] Completed Two-pointers --- src/ArrangeColors.java | 40 +++++++++ src/ContainerWithMostWater.java | 46 ++++++++++ src/TripletSum.java | 146 ++++++++++++++++++++++++++++++++ 3 files changed, 232 insertions(+) create mode 100644 src/ArrangeColors.java create mode 100644 src/ContainerWithMostWater.java create mode 100644 src/TripletSum.java diff --git a/src/ArrangeColors.java b/src/ArrangeColors.java new file mode 100644 index 00000000..f39ab9fa --- /dev/null +++ b/src/ArrangeColors.java @@ -0,0 +1,40 @@ +/* +Problem - Leetcode 75. Sort Colors +Approach - • +We move 0s to the front and 2s to the end, while keeping 1s in the middle. +Use three pointers: low for 0s, high for 2s, and mid to scan the array. +Swap accordingly and only move mid forward when the current item is 0 or 1. + */ +import java.util.Arrays; + +public class ArrangeColors { + public void sortColors(int[] nums) { + int low = 0; + int high = nums.length - 1; + int mid = 0; + while (mid <= high) { + if (nums[mid] == 2) { + swap(nums,mid,high); + high--; + } else if (nums[mid] == 0) { + swap(nums,mid,low); + mid++; + low++; + } + else { + mid++; + } + } + } + public void swap(int[] nums, int i, int j) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } + public static void main(String[] args) { + ArrangeColors a = new ArrangeColors(); + int[] nums = {2,0,2,1,1,0}; + a.sortColors(nums); + System.out.println(Arrays.toString(nums)); + } +} diff --git a/src/ContainerWithMostWater.java b/src/ContainerWithMostWater.java new file mode 100644 index 00000000..13027bc9 --- /dev/null +++ b/src/ContainerWithMostWater.java @@ -0,0 +1,46 @@ +/* +Problem - Container With Most Water +Approach - Start with two pointers at both ends and keep checking the area between them. +Move the pointer pointing to the shorter line. +Keep track of the maximum area found during this process. +Time Complexity - O(n) +Space Complexity - O(1) + */ +public class ContainerWithMostWater { + public int maxArea(int[] height) { + int maxArea = 0; + int left = 0; + int right = height.length - 1; + while (left < right) { + int h =0;// initializing height to compute the height on how the pointer moves + int width = right - left; + if(height[left]> to ensure uniqueness. + * + * Time Complexity: + * - Sorting: O(n log n) + * - Outer loop (i): O(n) + * - Inner loop (j): O(n) with O(1) average hash operations + * => Total: O(n^2) time (dominant), O(n) extra space per i (hash set), + * plus result storage. + * + * Note: Because we use HashSet>, we also do small constant work + * for list creation & sorting 3 elements. + * + * + * APPROACH 2: Two Pointers (classic optimal for 3Sum) + * 1) Sort nums. + * 2) Fix i as the first number: + * - Skip duplicate anchors. + * - If nums[i] > 0, break (since nums is sorted, sum can't be 0 anymore). + * 3) Use two pointers: low = i+1, high = n-1 + * - sum = nums[i] + nums[low] + nums[high] + * - sum == 0: record triplet, move both pointers, skip duplicates + * - sum > 0: need smaller sum => high-- + * - sum < 0: need larger sum => low++ + * + * Time Complexity: + * - Sorting: O(n log n) + * - Outer loop: O(n) + * - Two pointers scan per i: O(n) + * => Total: O(n^2) time, O(1) extra space (excluding output) + */ +public class TripletSum { + + public List> threeSum(int[] nums) { + HashSet> res = new HashSet<>(); + Arrays.sort(nums); + int n = nums.length; + int target = 0; + + for (int i = 0; i < n; i++) { + // Skip duplicate "anchor" values + if (i != 0 && nums[i] == nums[i - 1]) continue; + + HashSet set = new HashSet<>(); + int innerTarget = target - nums[i]; + + for (int j = i + 1; j < n; j++) { + int cmp = innerTarget - nums[j]; + + if (set.contains(cmp)) { + // Create triplet and normalize order (sorted) before adding to set + List list = Arrays.asList(nums[i], nums[j], cmp); + Collections.sort(list); // sorts 3 elements (constant work) + res.add(list); + } + set.add(nums[j]); + } + } + return new ArrayList<>(res); + } + + public List> threeSumWithTwoPointers(int[] nums) { + List> res = new ArrayList<>(); + Arrays.sort(nums); + int n = nums.length; + + for (int i = 0; i < n; i++) { + // Skip duplicate anchors + if (i != 0 && nums[i] == nums[i - 1]) continue; + + // Early stop: if nums[i] > 0, all remaining are >= nums[i], sum can't be 0 + if (nums[i] > 0) break; + + int low = i + 1, high = n - 1; + + while (low < high) { + int sum = nums[i] + nums[low] + nums[high]; + + if (sum == 0) { + res.add(Arrays.asList(nums[i], nums[low], nums[high])); + low++; + high--; + + // Skip duplicates for low and high + while (low < high && nums[low] == nums[low - 1]) low++; + while (low < high && nums[high] == nums[high + 1]) high--; + } else if (sum > 0) { + high--; + } else { + low++; + } + } + } + return res; + } + + private static void printTriplets(String title, List> triplets) { + System.out.println(title); + if (triplets.isEmpty()) { + System.out.println(" (no triplets)"); + return; + } + for (List t : triplets) { + System.out.println(" " + t); + } + } + + public static void main(String[] args) { + TripletSum solver = new TripletSum(); + + // Test cases (common LeetCode style) + int[][] tests = { + {-1, 0, 1, 2, -1, -4}, + {0, 1, 1}, + {0, 0, 0, 0}, + {-2, 0, 0, 2, 2}, + {-4, -2, -2, -2, 0, 1, 2, 2, 2, 3, 3, 4, 4, 6, 6} + }; + + for (int tc = 0; tc < tests.length; tc++) { + int[] nums1 = Arrays.copyOf(tests[tc], tests[tc].length); + int[] nums2 = Arrays.copyOf(tests[tc], tests[tc].length); + + System.out.println("===================================="); + System.out.println("Test #" + (tc + 1) + " Input: " + Arrays.toString(tests[tc])); + + List> ansHash = solver.threeSum(nums1); + List> ansTwoPtr = solver.threeSumWithTwoPointers(nums2); + + printTriplets("HashSet approach result:", ansHash); + printTriplets("Two Pointers approach result:", ansTwoPtr); + } + } +} +