Search Insert Position (LeetCode 35)
Given a sorted array of distinct integers and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
You must write an algorithm with O(log n) runtime complexity.
Example 1:
Input: nums = [1,3,5,6], target = 5
Output: 2
Example 2:
Input: nums = [1,3,5,6], target = 2
Output: 1
class Solution {
public int searchInsert(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) return mid;
else if (nums[mid] < target) left = mid + 1;
else right = mid - 1;
}
return left;
}
}class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return left| Type | Value |
|---|---|
| Time | O(log n) |
| Space | O(1) |
- Approach: Binary search; return insertion point when not found.
- Dry run (nums=[1,3,5,6], target=5):
- left=0,right=3 → mid=1,val=3 < 5 → left=2
- left=2,right=3 → mid=2,val=5 == 5 → return 2
Find First and Last Position of Element in Sorted Array (LeetCode 34)
34. Find First and Last Position of Element in Sorted Array
Given an array of integers
numssorted in non-decreasing order, find the starting and ending position of a giventargetvalue.
Iftargetis not found in the array, return[-1, -1].
You must write an algorithm withO(log n)runtime complexity.
Example 1:
Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]
Example 2:
Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]
Example 3:
Input: nums = [], target = 0
Output: [-1,-1]
class Solution {
public int[] searchRange(int[] nums, int target) {
return new int[]{find(nums, target, true), find(nums, target, false)};
}
private int find(int[] nums, int target, boolean isFirst) {
int left = 0, right = nums.length - 1;
int ans = -1;
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] == target) {
ans = mid;
if (isFirst) {
right = mid - 1;
} else {
left = mid + 1;
}
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return ans;
}
}class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
def find(is_first):
left, right = 0, len(nums) - 1
ans = -1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
ans = mid
if is_first:
right = mid - 1
else:
left = mid + 1
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return ans
return [find(True), find(False)]| Type | Value |
|---|---|
| Time | O(log n) |
| Space | O(1) |
- Approach: Perform two separate binary searches. One to find the first occurrence (when target is found, update answer and search left) and one to find the last occurrence (when target is found, update answer and search right).
- Dry run (nums=[5,7,7,8,8,10], target=8):
- First target binary search: target 8 found at index 4 -> ans=4, go left. Found at index 3 -> ans=3, go left. Finish at 3.
- Second target binary search: target 8 found at index 3 -> ans=3, go right. Found at index 4 -> ans=4, go right. Finish at 4.
- Return [3,4].
Find Minimum in Rotated Sorted Array (LeetCode 153)
153. Find Minimum in Rotated Sorted Array
Suppose an array of length n sorted in ascending order is rotated between 1 and n times. For example, the array nums = [0,1,2,4,5,6,7] might become:
[4,5,6,7,0,1,2]if it was rotated4times.[0,1,2,4,5,6,7]if it was rotated7times.
Notice that rotating an array [a[0], a[1], a[2], ..., a[n-1]] 1 time results in the array [a[n-1], a[0], a[1], a[2], ..., a[n-2]].
Given the sorted rotated array nums of unique elements, return the minimum element of this array.
You must write an algorithm that runs in O(log n) time.
Example 1:
Input: nums = [3,4,5,1,2]
Output: 1
Explanation: The original array was [1,2,3,4,5] rotated 3 times.
Example 2:
Input: nums = [4,5,6,7,0,1,2]
Output: 0
Explanation: The original array was [0,1,2,4,5,6,7] and it was rotated 4 times.
Example 3:
Input: nums = [11,13,15,17]
Output: 11
Explanation: The original array was [11,13,15,17] and it was rotated 4 times.
class Solution {
public int findMin(int[] nums) {
int s = 0;
int e = nums.length - 1;
while (s < e) {
int m = s + (e - s) / 2;
if (nums[m] <= nums[e]) {
e = m;
} else
s = m + 1;
}
return nums[s];
}
}class Solution:
def findMin(self, nums: List[int]) -> int:
s, e = 0, len(nums) - 1
while s < e:
m = s + (e - s) // 2
if nums[m] <= nums[e]:
e = m
else:
s = m + 1
return nums[s]| Type | Value |
|---|---|
| Time | O(log n) |
| Space | O(1) |
- Approach: Binary search focusing on the strictly increasing portion vs drop.
- Dry run (nums=[3,4,5,1,2]):
- m=2 (5) > nums[e] (2) -> s=3
- m=3 (1) <= nums[e] (2) -> e=3
- s=e=3 -> returns nums[3] = 1.
Search in Rotated Sorted Array (LeetCode 33)
33. Search in Rotated Sorted Array
There is an integer array
numssorted in ascending order (with distinct values).
Prior to being passed to your function,
numsis possibly left rotated at an unknown indexk(1 <= k < nums.length) such that the resulting array is[nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](0-indexed). For example,[0,1,2,4,5,6,7]might be left rotated by3indices and become[4,5,6,7,0,1,2].
Given the array
numsafter the possible rotation and an integertarget, return the index oftargetif it is innums, or-1if it is not innums.
You must write an algorithm with
O(log n)runtime complexity.
Example 1:
Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4
Example 2:
Input: nums = [4,5,6,7,0,1,2], target = 3
Output: -1
Example 3:
Input: nums = [1], target = 0
Output: -1
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] == target) {
return mid;
}
if (nums[left] <= nums[mid]) {
if (nums[left] <= target && target < nums[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
} else {
if (nums[mid] < target && target <= nums[right]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return -1;
}
}class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
if nums[left] <= nums[mid]:
if nums[left] <= target < nums[mid]:
right = mid - 1
else:
left = mid + 1
else:
if nums[mid] < target <= nums[right]:
left = mid + 1
else:
right = mid - 1
return -1| Type | Value |
|---|---|
| Time | O(log n) |
| Space | O(1) |
- Approach: Binary search. Identify which half of the array is sorted (
lefttomid, ormidtoright). If the target falls into the sorted half's range, move onto that half; otherwise, search the other half. - Dry run (nums = [4,5,6,7,0,1,2], target = 0):
- left=0, right=6: mid=3 (val 7). Target 0 != 7.
- Left half
[4,5,6,7]is sorted. Target 0 is NOT between 4 and 7. Thus move to right half: left = mid + 1 = 4. - left=4, right=6: mid=5 (val 1). Target 0 != 1.
- Right half
[1,2]is sorted. Target 0 is NOT between 1 and 2. Thus move to left half: right = mid - 1 = 4. - left=4, right=4: mid=4 (val 0). Target 0 == 0. Return 4.
Search in Rotated Sorted Array II (LeetCode 81)
81. Search in Rotated Sorted Array II
There is an integer array nums sorted in non-decreasing order (not necessarily with distinct values).
Before being passed to your function, nums is rotated at an unknown pivot index k (0 <= k < nums.length) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (0-indexed). For example, [0,1,2,4,4,4,5,6,6,7] might be rotated at pivot index 5 and become [4,5,6,6,7,0,1,2,4,4].
Given the array nums after the rotation and an integer target, return true if target is in nums, or false if it is not in nums.
You must decrease the overall operation steps as much as possible.
Example 1:
Input: nums = [2,5,6,0,0,1,2], target = 0
Output: true
Example 2:
Input: nums = [2,5,6,0,0,1,2], target = 3
Output: false
class Solution {
public boolean search(int[] nums, int target) {
int s = 0;
int e = nums.length - 1;
while (s <= e) {
int m = s + (e - s) / 2;
if (nums[m] == target)
return true;
if (nums[s] == nums[m] && nums[m] == nums[e]) {
s++;
e--;
continue;
}
if (nums[s] <= nums[m]) {
if (nums[s] <= target && target < nums[m])
e = m - 1;
else
s = m + 1;
} else {
if (nums[m] < target && target <= nums[e])
s = m + 1;
else
e = m - 1;
}
}
return false;
}
}class Solution:
def search(self, nums: List[int], target: int) -> bool:
s, e = 0, len(nums) - 1
while s <= e:
m = s + (e - s) // 2
if nums[m] == target: return True
if nums[s] == nums[m] == nums[e]:
s += 1
e -= 1
continue
if nums[s] <= nums[m]:
if nums[s] <= target < nums[m]: e = m - 1
else: s = m + 1
else:
if nums[m] < target <= nums[e]: s = m + 1
else: e = m - 1
return False| Type | Value |
|---|---|
| Time | O(log n) avg, O(n) worst |
| Space | O(1) |
- Approach: Binary Search with a minor tweak to handle duplicates. Skip same elements at edges.
- Dry run (nums = [2,5,6,0,0,1,2], target = 0):
- m=3 (val 0), target=0 -> returns true.
Kth Missing Positive Number (LeetCode 1539)
1539. Kth Missing Positive Number
Given an array
arrof positive integers sorted in a strictly increasing order, and an integerk.
Return thekthpositive integer that is missing from this array.
Example 1:
Input: arr = [2,3,4,7,11], k = 5
Output: 9
Explanation: The missing positive integers are [1,5,6,8,9,10,12,13,...]. The 5th missing positive integer is 9.
Example 2:
Input: arr = [1,2,3,4], k = 2
Output: 6
Explanation: The missing positive integers are [5,6,7,...]. The 2nd missing positive integer is 6.
class Solution {
public int findKthPositive(int[] arr, int k) {
int start = 0;
int end = arr.length - 1;
while (start <= end) {
int mid = start + (end - start) / 2;
int missingNumbersTillNow = arr[mid] - (mid + 1);
if (missingNumbersTillNow < k) {
start = mid + 1;
} else {
end = mid - 1;
}
}
return k + start;
}
}class Solution:
def findKthPositive(self, arr: List[int], k: int) -> int:
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
missing = arr[mid] - (mid + 1)
if missing < k:
left = mid + 1
else:
right = mid - 1
return left + k| Type | Value |
|---|---|
| Time | O(log n) |
| Space | O(1) |
- Approach: Use binary search. For any index
mid, the number of missing positive integers beforearr[mid]isarr[mid] - (mid + 1). If this count is less thank, the target must be to the right, so we setleft = mid + 1. Otherwise, it's to the left, so we setright = mid - 1. The kth missing number is thenleft + k. - Dry run (arr = [2,3,4,7,11], k = 5):
- l=0, r=4. mid=2, val=4. Missing till mid: 4 - (2+1) = 1 < 5 -> l=3
- l=3, r=4. mid=3, val=7. Missing till mid: 7 - (3+1) = 3 < 5 -> l=4
- l=4, r=4. mid=4, val=11. Missing till mid: 11 - (4+1) = 6 >= 5 -> r=3
- Loop ends. Return l + k = 4 + 5 = 9.
Koko Eating Bananas (LeetCode 875)
Koko loves to eat bananas. There are
npiles of bananas, theithpile haspiles[i]bananas. The guards have gone and will come back inhhours.
Koko can decide her bananas-per-hour eating speed ofk. Each hour, she chooses some pile of bananas and eatskbananas from that pile. If the pile has less thankbananas, she eats all of them instead and will not eat any more bananas during this hour.
Return the minimum integerksuch that she can eat all the bananas withinhhours.
Example 1:
Input: piles = [3,6,7,11], h = 8
Output: 4
Example 2:
Input: piles = [30,11,23,4,20], h = 5
Output: 30
Example 3:
Input: piles = [30,11,23,4,20], h = 6
Output: 23
class Solution {
public boolean canEat(int[] piles, int k, int h) {
long hours = 0;
for (int pile : piles) {
hours += (pile + k - 1) / k;
}
return hours <= h;
}
public int minEatingSpeed(int[] piles, int h) {
int left = 1;
int right = 0;
for (int pile : piles) {
right = Math.max(right, pile);
}
while (left < right) {
int mid = left + (right - left) / 2;
if (canEat(piles, mid, h)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
}import math
class Solution:
def canEat(self, piles: List[int], k: int, h: int) -> bool:
hours = 0
for pile in piles:
hours += math.ceil(pile / k)
return hours <= h
def minEatingSpeed(self, piles: List[int], h: int) -> int:
left, right = 1, max(piles)
while left < right:
mid = (left + right) // 2
if self.canEat(piles, mid, h):
right = mid
else:
left = mid + 1
return left| Type | Value |
|---|---|
| Time | O(n log m) |
| Space | O(1) |
- Approach: Binary search on the answer space. The minimum possible speed is 1, and the maximum is the maximum pile size (since she can only eat one pile per hour max). For each candidate speed
mid, we calculate if it's possible to eat all piles withinhhours. If yes, we search left (try slower). If no, we search right (go faster). - Dry run (piles=[3,6,7,11], h=8):
- l=1, r=11. mid=6. Hours: CEIL(3/6)+CEIL(6/6)+CEIL(7/6)+CEIL(11/6)=1+1+2+2=6 <= 8 -> right=6.
- l=1, r=6. mid=3. Hours: CEIL(3/3)+CEIL(6/3)+CEIL(7/3)+CEIL(11/3)=1+2+3+4=10 > 8 -> left=4.
- l=4, r=6. mid=5. Hours: CEIL(3/5)+CEIL(6/5)+CEIL(7/5)+CEIL(11/5)=1+2+2+3=8 <= 8 -> right=5.
- l=4, r=5. mid=4. Hours: CEIL(3/4)+CEIL(6/4)+CEIL(7/4)+CEIL(11/4)=1+2+2+3=8 <= 8 -> right=4.
- loop ends, return 4.
Find Peak Element (LeetCode 162)
A peak element is an element that is strictly greater than its neighbors.
Given a 0-indexed integer array
nums, find a peak element, and return its index. If the array contains multiple peaks, return the index to any of the peaks.You may imagine that
nums[-1] = nums[n] = -∞. In other words, an element is always considered to be strictly greater than a neighbor that is outside the array.You must write an algorithm that runs in
O(log n)time.
Example 1:
Input: nums = [1,2,3,1]
Output: 2
Explanation: 3 is a peak element and your function should return the index number 2.
Example 2:
Input: nums = [1,2,1,3,5,6,4]
Output: 5
Explanation: Your function can return either index number 1 where the peak element is 2, or index number 5 where the peak element is 6.
class Solution {
public int findPeakElement(int[] nums) {
int left = 0;
int right = nums.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] > nums[mid + 1]) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
}class Solution:
def findPeakElement(self, nums: List[int]) -> int:
left = 0
right = len(nums) - 1
while left < right:
mid = left + (right - left) // 2
if nums[mid] > nums[mid + 1]:
right = mid
else:
left = mid + 1
return left| Type | Value |
|---|---|
| Time | O(log n) |
| Space | O(1) |
- Approach: Use binary search. If
nums[mid] > nums[mid + 1], a peak must exist on the left side (inclusive ofmid), so setright = mid. Otherwise, a peak must exist on the right side, so setleft = mid + 1. - Dry run (nums = [1,2,3,1]):
- left=0, right=3. mid=1. nums[1]=2 < nums[2]=3 -> left = mid + 1 = 2.
- left=2, right=3. mid=2. nums[2]=3 > nums[3]=1 -> right = mid = 2.
- left == right -> return left = 2.
Search a 2D Matrix (LeetCode 74)
You are given an
m x ninteger matrixmatrixwith the following two properties:
- Each row is sorted in non-decreasing order.
- The first integer of each row is greater than the last integer of the previous row.
Given an integer
target, returntrueiftargetis inmatrixorfalseotherwise.You must write a solution in
O(log(m * n))time complexity.
Example 1:
Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
Output: true
Example 2:
Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
Output: false
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return false;
}
int rows = matrix.length;
int cols = matrix[0].length;
int left = 0;
int right = rows * cols - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
int midVal = matrix[mid / cols][mid % cols];
if (midVal == target) {
return true;
} else if (midVal < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return false;
}
}class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
row = len(matrix)
col = len(matrix[0])
l = 0
r = row * col - 1
while l <= r:
mid = l + (r - l) // 2
curr = matrix[mid // col][mid % col]
if curr == target:
return True
elif curr < target:
l = mid + 1
else:
r = mid - 1
return False| Type | Value |
|---|---|
| Time | O(log(m * n)) |
| Space | O(1) |
- Approach: Treat the 2D matrix as a sorted 1D array of size
m * n. Perform binary search. The 1D indexmidmaps to the 2D indicesrow = mid / colsandcol = mid % cols. - Dry run (matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3):
- m=3, n=4. left=0, right=11.
- mid=5. matrix[5/4][5%4] = matrix[1][1] = 11.
- 11 > 3 -> right = mid - 1 = 4.
- mid=2. matrix[2/4][2%4] = matrix[0][2] = 5.
- 5 > 3 -> right = mid - 1 = 1.
- mid=0. matrix[0/4][0%4] = matrix[0][0] = 1.
- 1 < 3 -> left = mid + 1 = 1.
- mid=1. matrix[1/4][1%4] = matrix[0][1] = 3.
- 3 == 3 -> return true.