From d0f18ac8d6d29047bbffc342ab679948e12ca60f Mon Sep 17 00:00:00 2001 From: Neel Date: Sat, 23 Aug 2025 21:46:04 -0400 Subject: [PATCH] Binary-search 2 done --- problem1.java | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++ problem2.java | 38 +++++++++++++++++++++++ problem3.java | 35 ++++++++++++++++++++++ 3 files changed, 156 insertions(+) create mode 100644 problem1.java create mode 100644 problem2.java create mode 100644 problem3.java diff --git a/problem1.java b/problem1.java new file mode 100644 index 00000000..be68f6f6 --- /dev/null +++ b/problem1.java @@ -0,0 +1,83 @@ +// Time Complexity : O(log n) +// Space Complexity : O(1) +// Did this code successfully run on Leetcode : yes +// Any problem you faced while coding this : no + + +// Your code here along with comments explaining your approach in three sentences only + +/** + * we find the first occurrence of the element by comparing the element with its left neighbor via doing binary search in whole array + * Then we find the last occurrence of the element by comparing the element with its right neighbor via doing binary search between first occurrence and end of array + */ +class Solution { + public int[] searchRange(int[] nums, int target) { + if (nums == null || nums.length == 0) return new int[]{-1, -1}; + + int n = nums.length; + //find the first occurrence + int first = findFirstOccurrence(nums, 0, n - 1, target); + // first match was not found so target doesn't exist + if (first == -1) return new int[]{-1, -1}; + int second = findSecondOccurrence(nums, first, n - 1, target); + + return new int[]{first, second}; + } + + private int findFirstOccurrence(int[] nums, int low, int high, int target) { + while (low <= high) { + int mid = low + (high - low) / 2; + // match found + if (nums[mid] == target) { + // if match at first index or the first occurrence within array + if (mid == 0 || nums[mid - 1] < nums[mid]) { + return mid; + } + // reject the right half to find the first occurrence + else { + high = mid - 1; + } + } + // reject the right half to find the first occurrence + else if (nums[mid] > target) { + high = mid - 1; + } + // reject the left half to find the first occurrence + else { + low = mid + 1; + } + } + + // match not found + return -1; + } + + private int findSecondOccurrence(int[] nums, int low, int high, int target) { + while (low <= high) { + int mid = low + (high - low) / 2; + // match found + if (nums[mid] == target) { + // if match at last index or last occurrence within array + if (mid == nums.length - 1 || nums[mid] < nums[mid + 1]) { + return mid; + } + // reject the left half to find the last occurrence + else { + low = mid + 1; + } + } + // reject the left half to find the last occurrence + else if (nums[mid] < target) { + low = mid + 1; + } + // reject the right half to find the last occurrence + else { + high = mid - 1; + } + } + + // unreachable since we found the first match + return -1; + } + +} \ No newline at end of file diff --git a/problem2.java b/problem2.java new file mode 100644 index 00000000..7bd5eacf --- /dev/null +++ b/problem2.java @@ -0,0 +1,38 @@ +// Time Complexity : O(log n) +// Space Complexity : O(1) +// Did this code successfully run on Leetcode : yes +// Any problem you faced while coding this : no + + +// Your code here along with comments explaining your approach in three sentences only + +/** + * we find the minimum via doing binary search on the array and discarding the sorted side since the minimum element can't exist in the sorted side + */ +class Solution { + public int findMin(int[] nums) { + if (nums.length == 1) return nums[0]; + + int n = nums.length; + int low = 0; + int high = n - 1; + + while (low <= high) { + int mid = low + (high - low) / 2; + // if we found the low on unsorted side, we found the match + if (nums[low] < nums[high]) return nums[low]; + // if number is smaller than its both neighbors, we found the match + if ((mid == 0 || nums[mid] < nums[mid - 1]) && (mid == n - 1 || nums[mid] < nums[mid + 1])) + return nums[mid]; + // left is sorted so ignoring the left side since number can't exist here + else if (nums[low] <= nums[mid]) + low = mid + 1; + // rihgt is sorted so ignoring the right side since number can't exist here + else + high = mid - 1; + } + + // unreachable + return -1; + } +} \ No newline at end of file diff --git a/problem3.java b/problem3.java new file mode 100644 index 00000000..253df100 --- /dev/null +++ b/problem3.java @@ -0,0 +1,35 @@ +// Time Complexity : O(log n) +// Space Complexity : O(1) +// Did this code successfully run on Leetcode : yes +// Any problem you faced while coding this : no + + +// Your code here along with comments explaining your approach in three sentences only + +/** + * we perform binary search and compare the pivot element with its left and right neighbors to find the peak + * if the pivot element was not bigger than its immediate neighbors, then we move to the number on the bigger side since we will eventually hit the peak because the boundary outside of the array is minus infinity + */ +class Solution { + public int findPeakElement(int[] nums) { + + int n = nums.length; + int low = 0; + int high = n - 1; + + while (low <= high) { + int mid = low + (high - low) / 2; + // if number is greather than both neighbors or we reached the end of the array on either side + if ((mid == 0 || nums[mid] > nums[mid - 1]) && (mid == n - 1 || nums[mid] > nums[mid + 1])) + return mid; + // since we have to find the peak, we have to move to the side where bigger number than current number exists + else if (nums[mid] < nums[mid + 1]) + low = mid + 1; + else + high = mid - 1; + } + + // unreachable + return -1; + } +} \ No newline at end of file