-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7c94483
commit eb18eba
Showing
15 changed files
with
585 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i]. | ||
# | ||
# Example 1: | ||
# | ||
# Input: nums = [5,2,6,1] | ||
# Output: [2,1,1,0] | ||
# Explanation: | ||
# To the right of 5 there are 2 smaller elements (2 and 1). | ||
# To the right of 2 there is only 1 smaller element (1). | ||
# To the right of 6 there is 1 smaller element (1). | ||
# To the right of 1 there is 0 smaller element. | ||
# | ||
# Example 2: | ||
# | ||
# Input: nums = [-1] | ||
# Output: [0] | ||
# | ||
# Example 3: | ||
# | ||
# Input: nums = [-1,-1] | ||
# Output: [0,0] | ||
# | ||
# Constraints: | ||
# | ||
# 1 <= nums.length <= 10^5 | ||
# -10^4 <= nums[i] <= 10^4 | ||
|
||
|
||
# 1) Binary Search | ||
# Traverse from the back to the beginning of the array, maintain a sorted array of numbers that have been visited. | ||
# Use binary search to find the first element in the sorted array which is larger or equal to target number. | ||
# For example, [5,2,3,6,1], when we reach 2, we have a sorted array [1,3,6], binary search returns 1, | ||
# which is the index where 2 should be inserted and is also the number smaller than 2. | ||
# Then we insert 2 into the sorted array to form [1,2,3,6]. | ||
class Solution: | ||
def countSmaller(self, nums: List[int]) -> List[int]: | ||
if not nums: | ||
return [] | ||
if len(nums) == 1: | ||
return [0] | ||
res = [0] * len(nums) | ||
sorted = [] | ||
for i in range(len(nums) - 1, -1, -1): | ||
idx = self.lower_bound(sorted, nums[i]) | ||
res[i] = idx | ||
sorted.insert(idx, nums[i]) | ||
return res | ||
|
||
def lower_bound(self, nums: List[int], target: int) -> int: | ||
l = 0 | ||
r = len(nums) | ||
while l < r: | ||
m = (l + r) // 2 | ||
if nums[m] < target: # Note < | ||
l = m + 1 | ||
else: | ||
r = m | ||
return l | ||
|
||
|
||
# 2) Binary Search, similar to 1) | ||
import bisect | ||
|
||
|
||
class Solution: | ||
def countSmaller(self, nums: List[int]) -> List[int]: | ||
if not nums: | ||
return [] | ||
if len(nums) == 1: | ||
return [0] | ||
res = [0] * len(nums) | ||
sorted = [] | ||
for i in range(len(nums) - 1, -1, -1): | ||
idx = bisect.bisect_left(sorted, nums[i]) | ||
res[i] = idx | ||
sorted.insert(idx, nums[i]) | ||
return res |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money. | ||
# Return the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1. | ||
# You may assume that you have an infinite number of each kind of coin. | ||
# | ||
# Example 1: | ||
# | ||
# Input: coins = [1,2,5], amount = 11 | ||
# Output: 3 | ||
# Explanation: 11 = 5 + 5 + 1 | ||
# | ||
# Example 2: | ||
# | ||
# Input: coins = [2], amount = 3 | ||
# Output: -1 | ||
# | ||
# Example 3: | ||
# | ||
# Input: coins = [1], amount = 0 | ||
# Output: 0 | ||
# | ||
# Constraints: | ||
# | ||
# 1 <= coins.length <= 12 | ||
# 1 <= coins[i] <= 2^31 - 1 | ||
# 0 <= amount <= 10^4 | ||
|
||
|
||
# 1) Dynamic Programming | ||
# Similar | ||
# 279. Perfect Squares | ||
# 300. Longest Increasing Subsequence | ||
# 322. Coin Change | ||
# | ||
# https://leetcode.com/problems/coin-change/discuss/77377/Javascript-Solution-(faster-than-90%2B-submissions)-*added-explanation | ||
# changes is an array to store the least amount of coins we need to make up a certain amount of money, the index of | ||
# changes means the amount of money to make up, so changes[x] means to make up money amount x how many coins we need at least | ||
# | ||
# Now, imagine if changes[0] ... to changes[10] is already known, and we need to calculate changes[11], coins = [1, 2, 5], | ||
# we know we have to take at least one coin from coins list otherwise we won't be able to make up 11 | ||
# | ||
# If we take coins[0] which has value 1, and now the total amount of money we need to make up becomes 10, and how many | ||
# coins we need at least to make up 10 is known already as changes[10], so if we take coins[0] to make up amount 11, | ||
# the least amount of coins we need will be 1 + changes[10] | ||
# | ||
# If we take coins[1] which has value 2, the least amount of coins we need will be 1 + changes[9] | ||
# If we take coins[2] which has value 5, the least amount of coins we need will be 1 + changes[6] | ||
# | ||
# changes[11] = min(1 + changes[10], 1 + changes[9], 1 + changes[6]) | ||
# | ||
# From the explanation above, we can see that to calculate changes[x], we will need to know the values from changes[0] | ||
# to changes[x-1], so in order to know changes[x] we start to calculate from changes[0] | ||
# | ||
# Corner cases are when the amount remaining to make up is less than the coin value, in this case, we simply continue | ||
# to the next coin, and if all coins values are greater than the amount to make up (changes[amount] will equal to | ||
# Infinity), that means we don't have any coin to make up that amount, so return -1 | ||
# | ||
# e.g. coins = [1, 2, 5], amount = 11 | ||
# dp = | ||
# [0, 1, I, I, I, I, I, I, I, I, I, I] # "I" stands for Infinity | ||
# [0, 1, 1, I, I, I, I, I, I, I, I, I] | ||
# [0, 1, 1, 2, I, I, I, I, I, I, I, I] | ||
# [0, 1, 1, 2, 2, I, I, I, I, I, I, I] | ||
# [0, 1, 1, 2, 2, 1, I, I, I, I, I, I] | ||
# [0, 1, 1, 2, 2, 1, 2, I, I, I, I, I] | ||
# [0, 1, 1, 2, 2, 1, 2, 2, I, I, I, I] | ||
# [0, 1, 1, 2, 2, 1, 2, 2, 3, I, I, I] | ||
# [0, 1, 1, 2, 2, 1, 2, 2, 3, 3, I, I] | ||
# [0, 1, 1, 2, 2, 1, 2, 2, 3, 3, 2, I] | ||
# [0, 1, 1, 2, 2, 1, 2, 2, 3, 3, 2, 3] | ||
class Solution: | ||
def coinChange(self, coins: List[int], amount: int) -> int: | ||
dp = [float("inf")] * (amount + 1) | ||
dp[0] = 0 | ||
for i in range(1, amount + 1): | ||
for coin in coins: | ||
if i >= coin: | ||
dp[i] = min(dp[i], dp[i - coin] + 1) | ||
return dp[amount] if dp[amount] != float("inf") else -1 | ||
|
||
|
||
# 2) DFS + Greedy + Pruning | ||
# https://youtu.be/uUETHdijzkA |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# Given an integer array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3].... | ||
# You may assume the input array always has a valid answer. | ||
# | ||
# Example 1: | ||
# | ||
# Input: nums = [1,5,1,1,6,4] | ||
# Output: [1,6,1,5,1,4] | ||
# Explanation: [1,4,1,5,1,6] is also accepted. | ||
# | ||
# Example 2: | ||
# | ||
# Input: nums = [1,3,2,2,3,1] | ||
# Output: [2,3,1,3,1,2] | ||
# | ||
# Constraints: | ||
# | ||
# 1 <= nums.length <= 5 * 10^4 | ||
# 0 <= nums[i] <= 5000 | ||
# It is guaranteed that there will be an answer for the given input nums. | ||
# | ||
# Follow Up: Can you do it in O(n) time and/or in-place with O(1) extra space? | ||
|
||
|
||
# 1) | ||
class Solution: | ||
def wiggleSort(self, nums: List[int]) -> None: | ||
""" | ||
Do not return anything, modify nums in-place instead. | ||
""" | ||
nums.sort() | ||
l = len(nums) | ||
m = l // 2 | ||
k = m - 1 if l % 2 == 0 else m # middle index | ||
|
||
copy = nums[:] | ||
j = l - 1 | ||
for i in range(0, l, 2): | ||
nums[i] = copy[k] | ||
if i < l - 1: | ||
nums[i + 1] = copy[j] | ||
k -= 1 | ||
j -= 1 | ||
|
||
|
||
# 2) | ||
# https://leetcode.com/problems/wiggle-sort-ii/discuss/77682/Step-by-step-explanation-of-index-mapping-in-Java |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# Given an integer n, return true if it is a power of three. Otherwise, return false. | ||
# An integer n is a power of three, if there exists an integer x such that n == 3x. | ||
# | ||
# Example 1: | ||
# | ||
# Input: n = 27 | ||
# Output: true | ||
# | ||
# Example 2: | ||
# | ||
# Input: n = 0 | ||
# Output: false | ||
# | ||
# Example 3: | ||
# | ||
# Input: n = 9 | ||
# Output: true | ||
# | ||
# Constraints: | ||
# | ||
# -2^31 <= n <= 2^31 - 1 | ||
|
||
|
||
# 1) | ||
# Time O(log n). In our case that is O(log3 n). The number of divisions is given by that logarithm. | ||
# Space O(1) | ||
class Solution: | ||
def isPowerOfThree(self, n: int) -> bool: | ||
if n <= 0: | ||
return False | ||
while n % 3 == 0: | ||
n /= 3 | ||
return n == 1 | ||
|
||
|
||
# 2) Mathematics | ||
# n = 3^i | ||
# i = log3(n) | ||
# i = log10(n) / log10(3) | ||
import math | ||
|
||
|
||
class Solution: | ||
def isPowerOfThree(self, n: int) -> bool: | ||
# using % 1 to get the decimal part | ||
return n > 0 and (math.log10(n) / math.log10(3)) % 1 == 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Given the head of a singly linked list, group all the nodes with odd indices together followed by the nodes with even indices, and return the reordered list. | ||
# The first node is considered odd, and the second node is even, and so on. | ||
# Note that the relative order inside both the even and odd groups should remain as it was in the input. | ||
# You must solve the problem in O(1) extra space complexity and O(n) time complexity. | ||
# | ||
# Example 1: | ||
# | ||
# Input: head = [1,2,3,4,5] | ||
# Output: [1,3,5,2,4] | ||
# | ||
# Example 2: | ||
# | ||
# Input: head = [2,1,3,5,6,4,7] | ||
# Output: [2,3,6,7,1,5,4] | ||
# | ||
# Constraints: | ||
# | ||
# The number of nodes in the linked list is in the range [0, 10^4]. | ||
# -10^6 <= Node.val <= 10^6 | ||
|
||
|
||
# Definition for singly-linked list. | ||
# class ListNode: | ||
# def __init__(self, val=0, next=None): | ||
# self.val = val | ||
# self.next = next | ||
|
||
|
||
# Notion | ||
|
||
# Time O(n) | ||
# Space O(1) | ||
class Solution: | ||
def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
if not head: | ||
return None | ||
|
||
odd = head | ||
even = head.next | ||
|
||
even_head = even | ||
while even and even.next: | ||
odd.next = even.next | ||
odd = odd.next | ||
even.next = odd.next | ||
even = even.next | ||
odd.next = even_head | ||
return head |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# Given an m x n integers matrix, return the length of the longest increasing path in matrix. | ||
# From each cell, you can either move in four directions: left, right, up, or down. You may not move diagonally or move outside the boundary (i.e., wrap-around is not allowed). | ||
# | ||
# Example 1: | ||
# | ||
# Input: matrix = [[9,9,4],[6,6,8],[2,1,1]] | ||
# Output: 4 | ||
# Explanation: The longest increasing path is [1, 2, 6, 9]. | ||
# | ||
# Example 2: | ||
# | ||
# Input: matrix = [[3,4,5],[3,2,6],[2,2,1]] | ||
# Output: 4 | ||
# Explanation: The longest increasing path is [3, 4, 5, 6]. Moving diagonally is not allowed. | ||
# | ||
# Example 3: | ||
# | ||
# Input: matrix = [[1]] | ||
# Output: 1 | ||
# | ||
# Constraints: | ||
# | ||
# m == matrix.length | ||
# n == matrix[i].length | ||
# 1 <= m, n <= 200 | ||
# 0 <= matrix[i][j] <= 2^31 - 1 | ||
|
||
|
||
# Backtracking + Memoization | ||
class Solution: | ||
def longestIncreasingPath(self, matrix: List[List[int]]) -> int: | ||
if not matrix: | ||
return 0 | ||
m, n = len(matrix), len(matrix[0]) | ||
dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)] | ||
cache = [[None] * n for _ in range(m)] | ||
|
||
def go(x, y): | ||
if cache[x][y] is not None: | ||
return cache[x][y] | ||
mx = 1 | ||
for dx, dy in dirs: | ||
i = x + dx | ||
j = y + dy | ||
if 0 <= i < m and 0 <= j < n and matrix[i][j] > matrix[x][y]: | ||
mx = max(mx, go(i, j) + 1) | ||
cache[x][y] = mx | ||
return mx | ||
|
||
mx = 0 | ||
for i in range(m): | ||
for j in range(n): | ||
mx = max(mx, go(i, j)) | ||
return mx |
Oops, something went wrong.