Skip to content

Commit

Permalink
feat(python): solutions
Browse files Browse the repository at this point in the history
  • Loading branch information
hongbo-miao committed Mar 31, 2022
1 parent a512478 commit 4e3577c
Show file tree
Hide file tree
Showing 14 changed files with 577 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ const searchRange3 = (nums, target) => {

while (l < r) {
const m = Math.ceil((l + r) / 2); // note using Math.ceil

if (nums[m] > target) r = m - 1;
else l = m;
}
Expand Down Expand Up @@ -86,7 +85,6 @@ const searchRange = (nums, target) => {

while (l < r) {
const m = Math.ceil((l + r) / 2); // note using Math.ceil

if (nums[m] > target) r = m - 1;
else l = m;
}
Expand Down
16 changes: 8 additions & 8 deletions JavaScript/0038. Count and Say.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,26 @@
* @return {string}
*/
const countAndSay = (n) => {
let res = '1';
for (let i = 1; i < n; i++) {
res = say(res);
let s = '1';
for (let i = 0; i < n - 1; i++) {
s = say(s);
}
return res;
return s;
};

const say = (s) => {
let res = '';
let count = 0;
let num = s[0];
let n = s[0];

for (let i = 0; i < s.length; i++) {
if (s[i] === num) {
if (s[i] === n) {
count++;
} else {
res += count + s[i - 1];
count = 1;
num = s[i];
n = s[i];
}
}
return res + count + num;
return res + count + n;
};
1 change: 1 addition & 0 deletions JavaScript/0041. First Missing Positive.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
// i++
// i = 3
// i++
// i = 4
const firstMissingPositive = (nums) => {
const swap = (i, j) => [nums[i], nums[j]] = [nums[j], nums[i]];

Expand Down
3 changes: 1 addition & 2 deletions JavaScript/0069. Sqrt(x).js
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ const mySqrt = (x) => {
const m = ~~((l + r) / 2);

if (m * m === x) return m;

if (m * m < x) l = m + 1;
else if (m * m < x) l = m + 1;
else r = m - 1;
}
return r;
Expand Down
4 changes: 2 additions & 2 deletions Python/0005. Longest Palindromic Substring.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ class Solution:
def longestPalindrome(self, s: str) -> str:
res = ""
for i in range(len(s)):
s1 = self.expend_from_center(s, i, i)
s1 = Solution.expend_from_center(s, i, i)
if len(s1) > len(res):
res = s1
s2 = self.expend_from_center(s, i, i + 1)
s2 = Solution.expend_from_center(s, i, i + 1)
if len(s2) > len(res):
res = s2
return res
Expand Down
26 changes: 26 additions & 0 deletions Python/0029. Divide Two Integers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Given two integers dividend and divisor, divide two integers without using multiplication, division, and mod operator.
# The integer division should truncate toward zero, which means losing its fractional part. For example, 8.345 would be truncated to 8, and -2.7335 would be truncated to -2.
# Return the quotient after dividing dividend by divisor.
#
# Note: Assume we are dealing with an environment that could only store integers within the 32-bit signed integer range: [−2^31, 2^31 − 1]. For this problem, if the quotient is strictly greater than 2^31 - 1, then return 2^31 - 1, and if the quotient is strictly less than -2^31, then return -2^31.
#
# Example 1:
#
# Input: dividend = 10, divisor = 3
# Output: 3
# Explanation: 10/3 = 3.33333.. which is truncated to 3.
#
# Example 2:
#
# Input: dividend = 7, divisor = -3
# Output: -2
# Explanation: 7/-3 = -2.33333.. which is truncated to -2.
#
# Constraints:
#
# -2^31 <= dividend, divisor <= 2^31 - 1
# divisor != 0


class Solution:
def divide(self, dividend: int, divisor: int) -> int:
98 changes: 98 additions & 0 deletions Python/0033. Search in Rotated Sorted Array.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# There is an integer array nums sorted in ascending order (with distinct values).
# Prior to being passed to your function, nums is possibly rotated at an unknown pivot index k (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 rotated at pivot index 3 and become [4,5,6,7,0,1,2].
# Given the array nums after the possible rotation and an integer target, return the index of target if it is in nums, or -1 if it is not in nums.
# 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
#
# Constraints:
#
# 1 <= nums.length <= 5000
# -10^4 <= nums[i] <= 10^4
# All values of nums are unique.
# nums is an ascending array that is possibly rotated.
# -10^4 <= target <= 10^4


# 1) Binary search
# https://leetcode.com/problems/search-in-rotated-sorted-array/discuss/273622/Javascript-Simple-O(log-N)-Binary-Search-Solution
#
# Time O(log n)
# Space O(1)
#
# e.g. [1, 2, 3, 4, 5, 6, 7]
#
# When you divide the rotated array into two halves, using mid index, at least one of them should remain sorted ALWAYS.
#
# [3, 4, 5] [6, 7, 1, 2] the left side remains sorted
# [6, 7, 1] [2, 3, 4, 5] the right side remains sorted
# [1, 2, 3] [4, 5, 6, 7] Both sides remain sorted.
#
# If you know one side is sorted, the rest of logic becomes very simple.
# If one side is sorted, check if the target is in the boundary, otherwise it's on the other side.
#
# IF smallest <= target <= biggest
# then target is here
# ELSE
# then target is on the other side
class Solution:
def search(self, nums: List[int], target: int) -> int:
l = 0
r = len(nums) - 1
while l <= r:
m = (l + r) // 2
if nums[m] == target:
return m

# When dividing the rotated array into two halves, one must be sorted
# Check if the left side is sorted
if nums[l] <= nums[m]:
if nums[l] <= target <= nums[m]:
r = m - 1 # target is in the left
else:
l = m + 1 # target is in the right
else:
if nums[m] <= target <= nums[r]:
l = m + 1 # target is in the right
else:
r = m - 1 # target is in the left
return -1


# 2) Binary search, similar to 1)
class Solution:
def search(self, nums: List[int], target: int) -> int:
l = 0
r = len(nums) - 1
while l + 1 < r:
m = (l + r) // 2
if nums[m] == target:
return m
if nums[l] < nums[m]: # e.g. 4, 5, 6, 7
if nums[l] <= target <= nums[m]:
r = m
else:
l = m
else: # e.g. 7, 0, 1, 2
if nums[m] <= target <= nums[r]:
l = m
else:
r = m
if nums[l] == target:
return l
if nums[r] == target:
return r
return -1
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Given an array of integers nums sorted in non-decreasing order, find the starting and ending position of a given target value.
# If target is not found in the array, return [-1, -1].
# You must write an algorithm with O(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]
#
# Constraints:
#
# 0 <= nums.length <= 10^5
# -10^9 <= nums[i] <= 10^9
# nums is a non-decreasing array.
# -10^9 <= target <= 10^9


# 1) Brute force / Linear scan
# Time O(n)
# Space O(1)


# 2) Binary search
# Time O(log n)
# Space O(1)
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
l = Solution.lower_bound(nums, target)
r = Solution.upper_bound(nums, target) - 1
if l <= r:
return [l, r]
return [-1, -1]

@staticmethod
def lower_bound(nums: List[int], target: int) -> int:
l = 0
r = len(nums)
while l < r:
m = (l + r) // 2
if nums[m] < target:
l = m + 1
else:
r = m
return l

@staticmethod
def upper_bound(nums: List[int], target: int) -> int:
l = 0
r = len(nums)
while l < r:
m = (l + r) // 2
if nums[m] <= target:
l = m + 1
else:
r = m
return l


# 3) Binary search, similar to 2)
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
l = Solution.lower_bound(nums, target)
r = Solution.lower_bound(nums, target + 1) - 1
if l <= r:
return [l, r]
return [-1, -1]

@staticmethod
def lower_bound(nums: List[int], target: int) -> int:
l = 0
r = len(nums)
while l < r:
m = (l + r) // 2
if nums[m] < target:
l = m + 1
else:
r = m
return l
Loading

0 comments on commit 4e3577c

Please sign in to comment.