written on 28 May 2023
Views : Loading...
Given an n x n matrix where each of the rows and columns is sorted in ascending order, return the kth smallest element in the matrix. Note that it is the kth smallest element in the sorted order, not the kth distinct element.
Algorithm:
def kthSmallest(matrix, k):
n = len(matrix)
low = matrix[0][0]
high = matrix[n-1][n-1]
while low <= high:
mid = (low + high) // 2
count = 0
j = n - 1
for i in range(n):
while j >= 0 and matrix[i][j] > mid:
j -= 1
count += j + 1
if count < k:
low = mid + 1
else:
high = mid - 1
return low
Given an integer array nums, return the length of the longest strictly increasing subsequence.
This is also called Patience Sorting algorithm.
Algorithm:
def lengthOfLIS(nums):
n = len(nums)
tails = [0] * n
size = 0
for x in nums:
left, right = 0, size
while left < right:
mid = (left + right) // 2
if tails[mid] < x:
left = mid + 1
else:
right = mid
tails[left] = x
size = max(size, left + 1)
return size
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.
Algorithm:
def find_peak_element(nums):
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if (mid == 0 or nums[mid] > nums[mid - 1]) and (mid == len(nums) - 1 or nums[mid] > nums[mid + 1]):
return mid
elif mid < len(nums) - 1 and nums[mid] < nums[mid + 1]:
left = mid + 1
else:
right = mid - 1
return -1
def searchRange(nums, target):
first = -1
last = -1
# Find first occurrence
left, right = 0, len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
first = mid
right = mid - 1
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
# Find last occurrence
left, right = 0, len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
last = mid
left = mid + 1
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return [first, last]
Given a rotated sorted array, search for a target element. The array does not contain any duplicates.
Algorithm:
def search(nums, target):
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
Given an integer array nums, return an integer array counts where counts[i] is the number of smaller elements to the right of nums[i].
This problem can be solved by Binary Search and Merge sort. Both have time complexity $O(N log N)$ and Space complexity $O(n)$. The merge sort approach is stable, meaning it preserves the relative order of elements with equal values. It ensures that elements with the same value are counted in the correct order. if stability is an important requirement, the merge sort approach is a better choice.
Algorithm:
def countSmaller(nums):
result = [0] * len(nums)
sorted_nums = []
for i in range(len(nums) - 1, -1, -1):
left, right = 0, len(sorted_nums)
while left < right:
mid = (left + right) // 2
if sorted_nums[mid] >= nums[i]:
right = mid
else:
left = mid + 1
result[i] = left
sorted_nums.insert(left, nums[i])
return result
Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays.
Time Complexity: $O(log ( min(m,n) ))$
Space Complexity: $O(1)$
Algorithm:
def findMedianSortedArrays(nums1, nums2):
if len(nums1) > len(nums2):
nums1, nums2 = nums2, nums1
x = len(nums1)
y = len(nums2)
low = 0
high = x
while low <= high:
partition_x = (low + high) // 2
partition_y = (x + y + 1) // 2 - partition_x
max_left_x = float('-inf') if partition_x == 0 else nums1[partition_x - 1]
min_right_x = float('inf') if partition_x == x else nums1[partition_x]
max_left_y = float('-inf') if partition_y == 0 else nums2[partition_y - 1]
min_right_y = float('inf') if partition_y == y else nums2[partition_y]
if max_left_x <= min_right_y and max_left_y <= min_right_x:
if (x + y) % 2 == 0:
return (max(max_left_x, max_left_y) + min(min_right_x, min_right_y)) / 2.0
else:
return max(max_left_x, max_left_y)
elif max_left_x > min_right_y:
high = partition_x - 1
else:
low = partition_x + 1
Suppose an array sorted in ascending order is rotated at some pivot unknown to you. Find the minimum element in logarithmic time complexity.
Approach:
def find_minimum(nums):
left = 0
right = len(nums) - 1
while nums[left] > nums[right]:
mid = (left + right) // 2
if nums[mid] > nums[right]:
left = mid + 1
else:
right = mid
return nums[left]
Given a 2D matrix where each row and column are sorted, write an efficient algorithm to search for a target element.
Required Time Complexity: $O(m+n)$
Algorithm:
The time complexity of $O(m + n)$ is the best time complexity achievable for this problem, considering that we need to examine at least one element from each row and column to determine the presence of the target.
def searchMatrix(matrix, target):
if not matrix or len(matrix[0]) == 0:
return False
rows, cols = len(matrix), len(matrix[0])
row, col = 0, cols - 1
while row < rows and col >= 0:
if matrix[row][col] == target:
return True
elif matrix[row][col] > target:
col -= 1
else:
row += 1
return False
Given a sorted array, two integers k and x, find the k closest elements to x in the array.
Algorithm:
def findClosestElements(arr, k, x):
left = 0
right = len(arr) - 1
while right - left + 1 > k:
diffLeft = abs(x - arr[left])
diffRight = abs(x - arr[right])
if diffLeft > diffRight:
left += 1
else:
right -= 1
return arr[left:right+1]
Thanks For Reading