diff --git a/121-best-time-to-buy-and-sell-stock/soln.py b/121-best-time-to-buy-and-sell-stock/soln.py new file mode 100644 index 0000000..25afad0 --- /dev/null +++ b/121-best-time-to-buy-and-sell-stock/soln.py @@ -0,0 +1,11 @@ +def maxProfit(self, prices: list[int]) -> int: + lowest = prices[0] + max_profit = 0 + + for x in prices[1:]: + if x - lowest > max_profit: + max_profit = x - lowest + if x < lowest: + lowest = x + + return max_profit diff --git a/122-best-time-to-buy-and-sell-stock-ii/soln.py b/122-best-time-to-buy-and-sell-stock-ii/soln.py new file mode 100644 index 0000000..93f7662 --- /dev/null +++ b/122-best-time-to-buy-and-sell-stock-ii/soln.py @@ -0,0 +1,8 @@ +def maxProfit(self, prices: list[int]) -> int: + cur_start = 0 + diff_sum = 0 + for idx in range(1, len(prices)): + if prices[idx] > prices[cur_start]: + diff_sum += prices[idx] - prices[cur_start] + cur_start = idx + return diff_sum diff --git a/169-majority-element/soln.py b/169-majority-element/soln.py new file mode 100644 index 0000000..ffacf67 --- /dev/null +++ b/169-majority-element/soln.py @@ -0,0 +1,26 @@ +def majorityElement(self, nums: list[int]) -> int: + # O(n) time, O(n) space + # cnts = {} + # for x in nums: + # cnts[x] = cnts.get(x, 0) + 1 + # if cnts[x] > len(nums) / 2: + # return x + + # O(n) time, O(1) space + # Boyer-Moore majority vote algorithm + # given: majority exists (>n/2, NOT just n/2) + # voters fight 1v1 MAD, last standing must be of majority + leading_candidate = nums[0] + count = 0 + for x in nums: + # MAD; new leader must emerge + if count == 0: + count = 1 + leading_candidate = x + # dissent; majority weakens + elif x != leading_candidate: + count -= 1 + # assent; majority strengthens + else: + count += 1 + return leading_candidate diff --git a/189-rotate-array/soln.py b/189-rotate-array/soln.py new file mode 100644 index 0000000..69ed716 --- /dev/null +++ b/189-rotate-array/soln.py @@ -0,0 +1,22 @@ +def rotate(self, nums: list[int], k: int) -> None: + """ + Do not return anything, modify nums in-place instead. + """ + # O(n) space and time + # n = len(nums) + # k %= n + # nums[:] = nums[n-k:] + nums[:n-k] + + # O(n) time, O(1) space + # reverse full - then reverse chunks + def partrev(arr, low, high): + while low < high: + arr[low], arr[high] = arr[high], arr[low] + low += 1 + high -= 1 + + n = len(nums) + k %= n + partrev(nums, 0, n - 1) + partrev(nums, 0, k - 1) + partrev(nums, k, n - 1) diff --git a/26-remove-duplicates-from-sorted-array/soln.py b/26-remove-duplicates-from-sorted-array/soln.py new file mode 100644 index 0000000..6712bba --- /dev/null +++ b/26-remove-duplicates-from-sorted-array/soln.py @@ -0,0 +1,19 @@ +class Solution: + def removeDuplicates(self, nums: list[int]) -> int: + # naive, hashmap + # cnts = {} + # k = 0 + # for x in nums: + # if cnts.get(x) == None: + # k += 1 + # cnts[x] = cnts.get(x, 0) + 1 + # for idx, key in enumerate(cnts.keys()): + # nums[idx] = key + # return k + # two pointer + last_unique = 0 + for fast in range(1, len(nums)): + if nums[last_unique] != nums[fast]: + last_unique += 1 + nums[last_unique] = nums[fast] + return last_unique + 1 # zero-indexed diff --git a/27-remove-element/soln.py b/27-remove-element/soln.py new file mode 100644 index 0000000..dc2e99f --- /dev/null +++ b/27-remove-element/soln.py @@ -0,0 +1,7 @@ +def removeElement(self, nums: list[int], val: int) -> int: + i = 0 + for x in nums: + if x != val: + nums[i] = x + i += 1 + return i diff --git a/45-jump-game-ii/soln.py b/45-jump-game-ii/soln.py new file mode 100644 index 0000000..d652b66 --- /dev/null +++ b/45-jump-game-ii/soln.py @@ -0,0 +1,17 @@ +def jump(self, nums: list[int]) -> int: + n = len(nums) + if n == 1: + return 0 + dp = [1e5] * n + dp[n - 1] = 0 + + for idx in range(n - 2, -1, -1): + for reach in range(0, nums[idx]): + # overshot, auto-success + if idx + reach + 1 >= n - 1: + dp[idx] = 1 + break + # else, chain-reachable + if dp[idx + reach + 1] <= 10000: + dp[idx] = min(dp[idx], dp[idx + reach + 1] + 1) + return dp[0] diff --git a/55-jump-game/soln.py b/55-jump-game/soln.py new file mode 100644 index 0000000..e706014 --- /dev/null +++ b/55-jump-game/soln.py @@ -0,0 +1,15 @@ +def canJump(self, nums: list[int]) -> bool: + n = len(nums) + if n == 1: + return True + if nums[0] == 0: + return False + dp = [False] * n + dp[n - 1] = True + + for idx in range(n - 2, -1, -1): + for reach in range(0, nums[idx]): + if dp[idx + reach + 1] == True: + dp[idx] = True + break + return dp[0] diff --git a/80-remove-duplicates-from-sorted-array-ii/soln.py b/80-remove-duplicates-from-sorted-array-ii/soln.py new file mode 100644 index 0000000..df8fba7 --- /dev/null +++ b/80-remove-duplicates-from-sorted-array-ii/soln.py @@ -0,0 +1,14 @@ +def removeDuplicates(self, nums: list[int]) -> int: + # two pointer + last_unique = 0 + flag = False + for fast in range(1, len(nums)): + if nums[last_unique] != nums[fast]: + flag = False + last_unique += 1 + nums[last_unique] = nums[fast] + elif not flag: + flag = True + last_unique += 1 + nums[last_unique] = nums[fast] + return last_unique + 1 # zero-indexed diff --git a/88-merge-sorted-array/soln.py b/88-merge-sorted-array/soln.py new file mode 100644 index 0000000..431a7aa --- /dev/null +++ b/88-merge-sorted-array/soln.py @@ -0,0 +1,27 @@ +def merge(self, nums1: list[int], m: int, nums2: list[int], n: int) -> None: + """ + Do not return anything, modify nums1 in-place instead. + """ + i = 0 + j = 0 + nums3 = [] + # one at a time + while i < m and j < n: + if nums1[i] < nums2[j]: + nums3.append(nums1[i]) + i += 1 + else: + nums3.append(nums2[j]) + j += 1 + + # deplete nums1 + while i < m: + nums3.append(nums1[i]) + i += 1 + # deplete nums2 + while j < n: + nums3.append(nums2[j]) + j += 1 + # optimize this? + for idx, val in enumerate(nums3): + nums1[idx] = val