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
83 changes: 83 additions & 0 deletions problem1.java
Original file line number Diff line number Diff line change
@@ -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;
}

}
38 changes: 38 additions & 0 deletions problem2.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
35 changes: 35 additions & 0 deletions problem3.java
Original file line number Diff line number Diff line change
@@ -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;
}
}