diff --git a/Problem1.java b/Problem1.java new file mode 100644 index 00000000..a44c352d --- /dev/null +++ b/Problem1.java @@ -0,0 +1,46 @@ +// I perform binary search twice: once to find the first occurrence and once to find the last occurrence. +// For each direction, I continue searching even after finding the target to ensure I locate the boundary index. +// This approach keeps the runtime O(log n) while accurately returning both start and end positions. +class Solution { + public int[] searchRange(int[] nums, int target) { + return new int[]{findFirst(nums, target), findLast(nums, target)}; + } + + private int findFirst(int[] nums, int target) { + int left = 0, right = nums.length - 1, index = -1; + + while (left <= right) { + int mid = left + (right - left) / 2; + + if (nums[mid] == target) { + index = mid; + right = mid - 1; // keep searching left + } else if (nums[mid] < target) { + left = mid + 1; + } else { + right = mid - 1; + } + } + + return index; + } + + private int findLast(int[] nums, int target) { + int left = 0, right = nums.length - 1, index = -1; + + while (left <= right) { + int mid = left + (right - left) / 2; + + if (nums[mid] == target) { + index = mid; + left = mid + 1; // keep searching right + } else if (nums[mid] < target) { + left = mid + 1; + } else { + right = mid - 1; + } + } + + return index; + } +} diff --git a/Problem2.java b/Problem2.java new file mode 100644 index 00000000..dea62efc --- /dev/null +++ b/Problem2.java @@ -0,0 +1,22 @@ +// I use binary search to determine which side of the array is sorted and then discard the sorted side +// because the minimum cannot lie there unless nums[mid] is the smallest element. +// By repeatedly narrowing the range toward the unsorted half, I can find the minimum in O(log n). + +class Solution { + public int findMin(int[] nums) { + int left = 0, right = nums.length - 1; + + while (left < right) { + int mid = left + (right - left) / 2; + + if (nums[mid] > nums[right]) { + left = mid + 1; // min must be to the right + } else { + right = mid; // mid might be the minimum + } + } + + return nums[left]; + } +} + diff --git a/Problem3.java b/Problem3.java new file mode 100644 index 00000000..4573e386 --- /dev/null +++ b/Problem3.java @@ -0,0 +1,22 @@ +// I apply binary search and compare mid with its next element to determine the direction of increasing slope. +// If nums[mid] < nums[mid+1], I move right because a peak must exist on that rising slope. +// Otherwise, I move left because the peak is on the left side or at mid itself. + +class Solution { + public int findPeakElement(int[] nums) { + int left = 0, right = nums.length - 1; + + while (left < right) { + int mid = left + (right - left) / 2; + + if (nums[mid] < nums[mid + 1]) { + left = mid + 1; // go right + } else { + right = mid; // go left or stay + } + } + + return left; // or right (same position) + } +} +