Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/ArrangeColors.java
Original file line number Diff line number Diff line change
@@ -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));
}
}
46 changes: 46 additions & 0 deletions src/ContainerWithMostWater.java
Original file line number Diff line number Diff line change
@@ -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]<height[right]) {
h = height[left]; // In this case, the left line is shorter than the right line, which means that the left line limits the water's height. Therefore, to find a larger container, let's move the left pointer inward to maximize the area
left++;
}
else {
h = height[right]; //In this case, the left line is shorter than the right line, which means that the left line limits the water's height. Therefore, to find a larger container, let's move the left pointer inward:
right--;
}
int area = h * width; // compute the area
maxArea = Math.max(maxArea, area); // compute the maxArea
}

return maxArea;
}
public static void main(String[] args) {
ContainerWithMostWater maxArea = new ContainerWithMostWater();
int[] heights = {};
System.out.println(maxArea.maxArea(heights));
int[] heights2 = {1};
System.out.println(maxArea.maxArea(heights2));
int[] heights3 = {0,1,0};
System.out.println(maxArea.maxArea(heights3));
int[] heights4 = {3, 3, 3, 3};
System.out.println(maxArea.maxArea(heights4));
int[] heights5 = {1, 2, 3};
System.out.println(maxArea.maxArea(heights5));
int[] heights6 = {1,8,6,2,5,4,8,3,7};
System.out.println(maxArea.maxArea(heights6));
}
}
146 changes: 146 additions & 0 deletions src/TripletSum.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import java.util.*;

/**
* 3Sum (Triplet Sum = 0)
*
* APPROACH 1: HashSet (for each i, solve 2Sum using a hash set)
* 1) Sort nums (helps handle duplicates & keeps triplets in consistent order).
* 2) Fix an index i as the first element.
* - Skip duplicate anchors (nums[i] == nums[i-1]) to avoid repeating work.
* 3) For the remaining part (j = i+1..n-1), use a HashSet to find complements:
* - innerTarget = 0 - nums[i]
* - if we have seen (innerTarget - nums[j]) before, we found a triplet.
* 4) Store triplets in a HashSet<List<Integer>> 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<List<Integer>>, 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<List<Integer>> threeSum(int[] nums) {
HashSet<List<Integer>> 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<Integer> 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<Integer> 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<List<Integer>> threeSumWithTwoPointers(int[] nums) {
List<List<Integer>> 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<List<Integer>> triplets) {
System.out.println(title);
if (triplets.isEmpty()) {
System.out.println(" (no triplets)");
return;
}
for (List<Integer> 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<List<Integer>> ansHash = solver.threeSum(nums1);
List<List<Integer>> ansTwoPtr = solver.threeSumWithTwoPointers(nums2);

printTriplets("HashSet approach result:", ansHash);
printTriplets("Two Pointers approach result:", ansTwoPtr);
}
}
}