leetcode question brushing (array - binary search)

Posted by EXiT on Sun, 19 Sep 2021 13:36:21 +0200

Binary search

  1. Binary search

Given an n-element ordered (ascending) integer array nums and a target value target, write a function to search the target in nums. If the target value exists, return the subscript, otherwise return - 1.

Example 1:

Input: num = [- 1,0,3,5,9,12], target = 9, output: 4
Explanation: 9 appears in nums and the subscript is 4

Example 2:

Input: num = [- 1,0,3,5,9,12], target = 2, output: - 1
Explanation: 2 does not exist in nums, so - 1 is returned

# python version
class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums) - 1
        
        while left <= right:
            middle = (left + right) // 2

            if nums[middle] < target:
                left = middle + 1
            elif nums[middle] > target:
                right = middle - 1
            else:
                return middle
        return -1

# java version
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){
                left = mid + 1;
            }else if(nums[mid]>target){
                right = mid - 1;
            }else{
                return mid;
            }
        }
        return -1;
    }
}
  1. Search insertion location

Given a sort array and a target value, find the target value in the array and return its index. If the target value does not exist in the array, returns the position where it will be inserted in order.

You must use an algorithm with a time complexity of O(log n).

Example 1:

Input: num = [1,3,5,6], target = 5, output: 2
Example 2:

Input: num = [1,3,5,6], target = 2, output: 1

# python
class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        n = len(nums)
        left = 0
        right = n - 1
        while(left<=right):
            mid = (left + right)//2
            if nums[mid]>target:
                right = mid - 1
            elif nums[mid]<target:
                left = mid + 1
            else:
            	# 1. The target value is equal to an element in the array return mid;
                return mid
        # 2. The target value is before all elements of the array. 3. The target value is inserted into the array. 4. The target value is after all elements of the array. return right + 1;
        return right+1
        
# java
class Solution {
    public int searchInsert(int[] nums, int target) {
        int n = nums.length;
        int left = 0;
        int right = n-1;
        while(left<=right){
            int mid = (left+right)/2;
            if(nums[mid]<target){
                left = mid + 1;
            }else if(nums[mid]>target){
                right = mid - 1;
            }else{
                return mid;
            }
        }
        return right + 1;
    }
}
  1. Finds the first and last positions of elements in a sorted array

Given an integer array nums arranged in ascending order and a target value target. Find the start and end positions of the given target value in the array.

If the target value target does not exist in the array, return [- 1, - 1].

Advanced:

Can you design and implement an algorithm with time complexity of O(log n) to solve this problem?

Example 1:

Input: num = [5,7,7,8,8,10], target = 8, output: [3,4]
Example 2:

Input: num = [5,7,7,8,8,10], target = 6, output: [- 1, - 1]

# python
class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
    	# Binary search to find the left boundary of target (excluding target)
        def getLeftBorder(nums,target):
            n = len(nums)
            left = 0
            right = n - 1
            leftBorder = -2
            while(left <= right):
                mid = (left + right)//2
                if nums[mid] >= target:
                    right = mid - 1
                    leftBorder = right
                else:   # nums[mid] < target
                    left = mid + 1
            return leftBorder
        # Binary search to find the right boundary of target (excluding target)
        def getRightBorder(nums,target):
            n = len(nums)
            left = 0
            right = n - 1
            rightBorder = -2
            while(left <= right):
                mid = (left + right)//2
                if nums[mid] <= target:
                    left = mid + 1
                    rightBorder = left
                else:   # nums[mid] > target
                    right = mid - 1
            return rightBorder
        leftBorder = getLeftBorder(nums,target)
        rightBorder = getRightBorder(nums,target)
        if(leftBorder == -2 or rightBorder == -2):
            return [-1,-1]
        elif((rightBorder-leftBorder)>1):
            return [leftBorder+1,rightBorder-1]
        else:
            return [-1,-1]
            
# java
class Solution {
    public int[] searchRange(int[] nums, int target) {
        int leftBorder = getLeftBorder(nums, target);
        int rightBorder = getRightBorder(nums, target);
        if(leftBorder==-2||rightBorder==-2){
            return new int[]{-1,-1};
        }else if(rightBorder-leftBorder>1){
            return new int[]{leftBorder+1,rightBorder-1};
        }else{
            return new int[]{-1,-1};
        }
    }
    public int getLeftBorder(int[] nums, int target){
            int n = nums.length;
            int left = 0;
            int right = n - 1;
            int leftBorder = -2;
            while(left<=right){
                int mid = (left+right)/2;
                if(nums[mid]<target){
                    left = mid + 1;
                }else{  //nums[mid]>=target
                    right = mid - 1;
                    leftBorder = right;
                }
            }
            return leftBorder;
        }
        public int getRightBorder(int[] nums, int target){
            int n = nums.length;
            int left = 0;
            int right = n - 1;
            int rightBorder = -2;
            while(left<=right){
                int mid = (left+right)/2;
                if(nums[mid]>target){
                    right = mid - 1;
                }else{  //nums[mid]<=target
                    left = mid + 1;
                    rightBorder = left;
                }
            }
            return rightBorder;
        }
}
  1. Square root of x

Give you a nonnegative integer x, calculate and return the square root of X.

Since the return type is an integer, only the integer part will be retained and the decimal part will be rounded off.

Note: it is not allowed to use any built-in exponential functions and operators, such as pow(x, 0.5) or x ** 0.5.

Example 1:

Input: x = 4 Output: 2
Example 2:

Input: x = 8 output: 2
Explanation: the square root of 8 is 2.82842... Because the return type is an integer, the decimal part will be rounded off.

# python
class Solution:
    def mySqrt(self, x: int) -> int:
        left = 0
        right = x 
        while(left<=right):
            mid = (left + right)//2
            if(mid*mid>x):
                right = mid - 1
            elif(mid*mid<x):
                left = mid + 1
            else:
                return mid
        return right

# java

class Solution {
    public int mySqrt(int x) {
        int left = 0;
        int right = x;
        while(left<=right){
            int mid = (left+right)/2;
            if((long)mid*mid<x){
                left = mid + 1;
            }else if((long)mid*mid>x){
                right = mid - 1;
            }else{
                return mid;
            }
        }
        return right;
    }
}
  1. Effective complete square

Given a positive integer num, write a function. If num is a complete square number, it returns true, otherwise it returns false.

Advanced: do not use any built-in library functions, such as sqrt.

Example 1:

Input: num = 16 output: true
Example 2:

Input: num = 14 output: false

# python
class Solution:
    def isPerfectSquare(self, num: int) -> bool:
        left = 0
        right = num
        while(left<=right):
            mid = (left+right)//2
            if(mid*mid<num):
                left = mid + 1
            elif(mid*mid>num):
                right = mid - 1
            else:
                return True
        return False

# java
class Solution {
    public boolean isPerfectSquare(int num) {
        int left = 0;
        int right = num;
        while(left<=right){
            int mid = (left+right)/2;
            if((long)mid*mid<num){
                left = mid + 1;
            }else if((long)mid*mid>num){
                right = mid - 1;
            }else{
                return true;
            }
        }
        return false;
    }
}

Topics: Algorithm data structure leetcode