From a5e800effe30d6fc011f6456d18e48d20fd04fb3 Mon Sep 17 00:00:00 2001 From: devoalda Date: Sat, 18 Feb 2023 08:38:54 +0800 Subject: [PATCH] Added 2 Leetcode Problems --- content/en/posts/Leetcode-BinarySearch704.md | 109 ++++++++++++++++++ .../en/posts/Leetcode-FirstBadVersion278.md | 98 ++++++++++++++++ 2 files changed, 207 insertions(+) create mode 100644 content/en/posts/Leetcode-BinarySearch704.md create mode 100644 content/en/posts/Leetcode-FirstBadVersion278.md diff --git a/content/en/posts/Leetcode-BinarySearch704.md b/content/en/posts/Leetcode-BinarySearch704.md new file mode 100644 index 0000000..fcc85cc --- /dev/null +++ b/content/en/posts/Leetcode-BinarySearch704.md @@ -0,0 +1,109 @@ +--- +author: "Devoalda" +authorEmoji: 🐺 +title: "Leetcode Binary Search (704)" +date: 2023-02-18T07:39:33+08:00 +description: Leetcode Challenge 704 +draft: false +hideToc: false +enableToc: true +enableTocContent: true +tocPosition: inner +tocLevels: ["h1", "h2", "h3"] +math: true +libraries: mathjax +tags: + - leetcode + - python +series: + - +categories: + - LeetCode + - python +image: +--- + +# Introduction + +Given an array of integers `nums` which is sorted in ascending order, +and an integer target, write a function to search target in `nums`. +If target exists, then return its index. Otherwise, return -1. + +You must write an algorithm with $O(\log n)$ runtime complexity. + +{{< tabs Example_1 Example_2 >}} +{{< tab >}} + +```shell +Input: nums = [-1,0,3,5,9,12], target = 9 +Output: 4 +Explanation: 9 exists in nums and its index is 4 +``` + +{{< /tab >}} + +{{< tab >}} + +```shell +Input: nums = [-1,0,3,5,9,12], target = 2 +Output: -1 +Explanation: 2 does not exist in nums so return -1 +``` + +{{< /tab >}} +{{< /tabs >}} + +# Process + +This is a normal binary search, splitting each search iteration by $\frac{1}{2}$, I created a new function with `left` and `right` variables to indicate the high and low pointers on the array. + +Since the array is already sorted in ascending order, the larger numbers will always be to the right of the mid value. +The mid index value could be found using the floor division of `left + right`: + +```python +mid = (left + right) // 2 +``` + +though I realise that using a right shift would make it faster + +```python +mid = (left + right) >> 1 +``` + +After getting the midpoint, there will be 3 conditions left: + +1. `nums[mid] == target` +2. `nums[mid] < target` +3. `nums[mid] > target` + +For each of this conditions, I'll update the pointers or return the mid value. this is all done in a while loop where `left` needs to be $\le$`right` and `left` should not go past `right` (Value Not Found). + +At the end, I'll return `-1` if the value isn't found. + +Calling the function in the return statement of the outer function definition, I'll pass `0` and `len(nums) -1` into the binary search function. + +This solution takes a Time Complexity of $O(\log n)$ and Space Complexity of $O(1)$ as it only requires the size of the array. + +# Solution + +```python +class Solution: + def search(self, nums: List[int], target: int) -> int: + def bSearch(left, right): + while left <= right: + mid = (left + right)//2 + if nums[mid] == target: + return mid + elif target < nums[mid]: + right = mid-1 + + else: + left = mid + 1 + return -1 + + return bSearch(0, len(nums)-1) +``` + +# Afterthoughts + +This is my first step into revising for my Data Structures and Algorithms. Binary search is one of the fastest searching algorithms, with $O(\log n)$ Time Complexity. Coupled with a fast Sorting algorithm, Users will be able to sort and search for values quickly and efficiently. diff --git a/content/en/posts/Leetcode-FirstBadVersion278.md b/content/en/posts/Leetcode-FirstBadVersion278.md new file mode 100644 index 0000000..f664154 --- /dev/null +++ b/content/en/posts/Leetcode-FirstBadVersion278.md @@ -0,0 +1,98 @@ +--- +author: "Devoalda" +authorEmoji: 🐺 +title: "Leetcode First Bad Version (278)" +date: 2023-02-18T08:39:33+08:00 +description: Leetcode Challenge 278 +draft: false +hideToc: false +enableToc: true +enableTocContent: true +tocPosition: inner +tocLevels: ["h1", "h2", "h3"] +math: true +libraries: mathjax +tags: + - leetcode + - python +series: + - +categories: + - LeetCode + - python +image: +--- + +# Introduction + +You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version of your product fails the quality check. Since each version is developed based on the previous version, all the versions after a bad version are also bad. + +Suppose you have `n` versions `[1, 2, ..., n]` and you want to find out the first bad one, which causes all the following ones to be bad. + +You are given an API bool `isBadVersion(version)` which returns whether version is bad. Implement a function to find the first bad version. You should minimize the number of calls to the API. + +{{< tabs Example_1 Example_2 >}} +{{< tab >}} + +```shell +Input: n = 5, bad = 4 +Output: 4 +Explanation: +call isBadVersion(3) -> false +call isBadVersion(5) -> true +call isBadVersion(4) -> true +Then 4 is the first bad version. +``` + +{{< /tab >}} + +{{< tab >}} + +```shell +Input: nums = [-1,0,3,5,9,12], target = 2 +Output: -1 +Explanation: 2 does not exist in nums so return -1 +``` + +{{< /tab >}} +{{< /tabs >}} + +# Process + +Using a binary search done in [Leetcode Binary Search 704]( {{< ref "posts/Leetcode-BinarySearch704.md" >}}), I was able to get the first bad version. + +First, I initialised my `left` variable to `1` as the lower limit was `1` and I couldn't start from 0. I initialised right to be `n` for the number of versions. + +In the same while loop, I calculated the mid index again, but this time with right shift. I first checked with the `isBadVersion` API for the midpoint. If it is true, I'll set the `firstIndex` variable to the midpoint, and the right index to `mid - 1` to check the left side. + +If the first condition is not met, I'll check the next half by updating `mid + 1` in the while loop. + +At the end of the loop, `firstIndex` is returned as the First Bad Version. + +This solution takes a Time Complexity of $O(\log n)$ and Space Complexity of $O(1)$ + +# Solution + +```python +# The isBadVersion API is already defined for you. +# def isBadVersion(version: int) -> bool: + +class Solution: + def firstBadVersion(self, n: int) -> int: + left = 1 + right = n + firstIndex = -1 + + while left <= right: + mid = (left + right) >> 1 + if isBadVersion(mid): + firstIndex = mid + right = mid - 1 + else: + left = mid + 1 + return firstIndex +``` + +# Afterthoughts + +This is almost a duplicate of [Leetcode Binary Search 704]( {{< ref "posts/Leetcode-BinarySearch704.md" >}}), where binary search is used as the most efficient algorithm, splitting the sorted array into half each time through the iteration to search for the values required. I need more practice to be familiar and comfortable with these searching algorithms.