Last month I got an email said would go back to office to work after labor day, not sure if will postpone or not because originaly said go back to office in July, then postponed to August, now is September. Anyway, Let’s continue September LeetCoding Challenge.
Week 1: September 1st - September 7th
Read N Characters Given Read4
Given a file and assume that you can only read the file using a given method read4
, implement a method to read n characters.
Method read4:
The API read4
reads 4 consecutive characters from the file, then writes those characters into the buffer array buf
.
The return value is the number of actual characters read.
Note that read4()
has its own file pointer, much like FILE *fp
in C.
Definition of read4:
1 |
|
Below is a high level example of how read4
works:
1 |
|
Method read:
By using the read4
method, implement the method read
that reads n characters from the file and store it in the buffer array buf
. Consider that you cannot manipulate the file directly.
The return value is the number of actual characters read.
Definition of read:
1 |
|
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Note:
-
Consider that you cannot manipulate the file directly, the file is only accesible for
read4
but not forread
. -
The
read
function will only be called once for each test case. -
You may assume the destination buffer array,
buf
, is guaranteed to have enough space for storing n characters.
Explanation
-
In this problem, we need to store
n
characters into thebuf[]
, so we cannot directly pass the inputbuf[]
intoread4()
. Instead, we can callread4()
with a temporary buffer array, then copy the temporary buffer array’s content intobuf[]
. When we copying, we need to record bothbuf[]
andtemp[]
’s index asbufIdx
andtempIdx
. At the end, we need to return the file’s content length which is thebufIdx
. -
First, we call
cnt = read4(temp)
wheretemp[]
stores the content andcnt
it’s the content length. Whilecnt
is not equal to 0 andbufIdx
is less thann
, we start copyingtemp[tempIdx]
intobuf[bufIdx]
. If we finish reading temporary buffer’s content, then we call theread4()
function and update the content lengthcnt
, and also resettempIdx
back to 0. -
Outside the while loop, it’s either the content length is 0 or
bufIdx
is equal ton
, so we stop and return thebufIdx
which is the number of character we read.
Solution
1 |
|
Largest Time for Given Digits
Given an array of 4 digits, return the largest 24 hour time that can be made.
The smallest 24 hour time is 00:00, and the largest is 23:59. Starting from 00:00, a time is larger if more time has elapsed since midnight.
Return the answer as a string of length 5. If no valid time can be made, return an empty string.
Example 1:
1 |
|
Example 2:
1 |
|
Note:
-
A.length == 4
-
0 <= A[i] <= 9
Explanation
-
We can find all 4! number of permutations and compare them to get the largest time.
-
The result will be
hh:mm
. We can loop the input array trying all possibilities for the firsth
, secondh
, firstm
and secondm
. Instead of 4 loops, we can have 3 loops because there are total 4 digits, if we know 3 digits, then we will know the last digit. -
To validate
hh
is from00
to23
, we can actually comparehh
and"23"
in string format (think about “abc” < “acb”) and make sure"hh" <= "23"
. Similarlly formm
cannot greater than"59"
.
Solution
1 |
|
Contains Duplicate III
Given an array of integers, find out whether there are two distinct indices i and j in the array such that the absolute difference between nums[i] and nums[j] is at most t and the absolute difference between i and j is at most k.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Hint 1:
Time complexity O(n logk) - This will give an indication that sorting is involved for k elements.
Hint 2:
Use already existing state to evaluate next state - Like, a set of k sorted numbers are only needed to be tracked. When we are processing the next number in array, then we can utilize the existing sorted state and it is not necessary to sort next overlapping set of k numbers again.
Explanation
- We can use brute force to solve this problem. We loop all pair of numbers by using 2 loops and compare these two numbers. If their absolute difference is less than or equal to
t
, then return true.
Solution
1 |
|
Repeated Substring Pattern
Given a non-empty string check if it can be constructed by taking a substring of it and appending multiple copies of the substring together. You may assume the given string consists of lowercase English letters only and its length will not exceed 10000.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Explanation
-
We can append the input string at the end of the input string. For example, if input string is
abab
then after appending, the new string isabababab
. -
Then, we check if the original string is inside the new string’s substrring
newStr.substring[1:-1]
. If inside, we return true. Otherwise, return false.
Solution
1 |
|
Partition Labels
A string S
of lowercase English letters is given. We want to partition this string into as many parts as possible so that each letter appears in at most one part, and return a list of integers representing the size of these parts.
Example 1:
1 |
|
Note:
-
S
will have length in range[1, 500]
. -
S
will consist of lowercase English letters ('a'
to'z'
) only.
Hint 1:
Try to greedily choose the smallest partition that includes the first letter. If you have something like “abaccbdeffed”, then you might need to add b. You can use an map like “last[‘b’] = 5” to help you expand the width of your partition.
Explanation
-
In this problem, the same characters can only be inside one group, and we need to make sure the there are as many groups as possible.
-
We notice that if a character appears many times, then the last same character and the current character are in the same group. From the problem’s example, character
a
,e
,j
are the last appear character in each group. So we need to find out every character’s last seen index. -
Next, we use a variable
end
represents the potential group or substring’s ending index, andstart
represent the group’s first index. They both initialize to 0. Then, we loop through the input string characters, in each iteration, we update theend
be the maximum last seen index. If the current indexi
is equals toend
, then we found one group since all the characterstr[i]
’s last seen index is not greater thanend
, so these characters are in the same group. We can calculate this group’s length beend - start + 1
. After we found one group, we need to updatestart = end + 1
.
Solution
1 |
|
All Elements in Two Binary Search Trees
Given two binary search trees root1
and root2
.
Return a list containing all the integers from both trees sorted in ascending order.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Example 5:
1 |
|
Constraints:
-
Each tree has at most
5000
nodes. -
Each node’s value is between
[-10^5, 10^5]
.
Hint 1:
Traverse the first tree in list1 and the second tree in list2.
Hint 2:
Merge the two trees in one list and sort it.
Explanation
- We can save space complexity by using the stack way of in-order traversal since the stack way will only save the number of height of the tree nodes, whereas recursive in-order will save all the nodes into a list.
Solution
1 |
|
Image Overlap
Two images A
and B
are given, represented as binary, square matrices of the same size. (A binary matrix has only 0s and 1s as values.)
We translate one image however we choose (sliding it left, right, up, or down any number of units), and place it on top of the other image. After, the overlap of this translation is the number of positions that have a 1 in both images.
(Note also that a translation does not include any kind of rotation.)
What is the largest possible overlap?
Example 1:
1 |
|
Notes:
-
1 <= A.length = A[0].length = B.length = B[0].length <= 30
-
0 <= A[i][j], B[i][j] <= 1
Explanation
-
This problem askes we can move the entire square left, right, up, or down. Then find the maximum number of overlap 1s. We can use brute force to solve this problem.
-
In one helper function, we fix
A
and moveB
down right. Then this is the same as moveA
up left and fixB
. We can use 2 for loops to try all possibility of movingB
down and right, then inside these 2 for loops, we create a countercur
to keep track of the number of overlapping 1s. Then we use another 2 for loops to iterate the overlapping part and count the overlap 1s. After counting, we update the global maximum of counterres
. Outside these 4 for loops, we return the global maximum counterres
. -
In another helper function, we fix
A
and moveB
up right. This is the same as moveA
down left and fixB
. Similarlly to the above helper function, we will use 4 for loops to calculate the maximum number of overlapping 1s. -
At the end, we return the maximum from the these 2 helper functions.
Solution
1 |
|
Word Pattern
Given a pattern
and a string str
, find if str
follows the same pattern.
Here follow means a full match, such that there is a bijection between a letter in pattern
and a non-empty word in str
.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Notes:
You may assume pattern
contains only lowercase letters, and str
contains lowercase letters that may be separated by a single space.
Explanation
-
We can use a hashmap to solve this problem.
-
First we check if the pattern length is not equal to the word length, then we simply return false. In the hashmap, we store key as pattern character, value as the word. Loop through each word.
-
If the hashmap doesn’t have the current pattern character as key, then we check if the current word is also not visited before, then we add the character and word into the map, and add the word into the visited set. But if the current word is visited before, then we return false. One example is
pattern = "abc", str = "dog dog dog"
. In this example, the map doesn’t have the pattern before, but the word is visited before, so we return false. -
If the hashmap have the current pattern character as key, then we simply compare its corresponding word with the iterated word. If they are not equal, then we return
false
. -
After looping every character and word, we return true.
Solution
1 |
|
Week 2: September 8th - September 14th
Moving Average from Data Stream
Given a stream of integers and a window size, calculate the moving average of all integers in the sliding window.
Example:
1 |
|
Explanation 1
-
We can use a queue as out sliding window. In the constructor method, we need to instinatiate the limit size, the sum, and the queue.
-
In the
next
method, first we check if the queue’s size is equal to the limit size, then we poll the first element out from the queue, andsum
needs to subtract this poll element. Next, we add the inputval
into the queue, and update thesum
. Now, we can return the result as sum / queueSize.
Solution 1
1 |
|
Explanation 2
- We can also use an array instead of queue to solve this problem. First, we need to create an array that has the same size as the limit size. How do we know which element we need to poll? We can use
tailIdx = (tailIdx + 1) % limitSize
to point to the next index that we will insert the element on. NowtailIdx
is in a loop of repeated value, if we have the same size as the limit size, the next index will be the oldest or first index we inserted. Before we update thesum
and insert the element intailIdx
of the array, we need to subtractarr[tailIdx]
fromsum
because initiallyarr[tailIdx] = 0
which is fine to subtract 0. But ifarr[tailIdx]
is not 0, that means we exceed the limit size so we need to subtractarr[tailIdx]
fromsum
.
Solution 2
1 |
|
Sum of Root To Leaf Binary Numbers
Given a binary tree, each node has value 0
or 1
. Each root-to-leaf path represents a binary number starting with the most significant bit. For example, if the path is 0 -> 1 -> 1 -> 0 -> 1
, then this could represent 01101
in binary, which is 13
.
For all leaves in the tree, consider the numbers represented by the path from the root to that leaf.
Return the sum of these numbers.
Example 1:
1 |
|
Note:
-
The number of nodes in the tree is between
1
and1000
. -
node.val is
0
or1
. -
The answer will not exceed
2^31 - 1
.
Hint 1:
Find each path, then transform that path to an integer in base 10.
Explanation
-
We can use recursion to solve this problem. For example, in the problem’s example, we need to pass the current root value
1
to both its left child and right child. When we are in the left child, we need to left shift the passed value1
by 1 then add the current node’s value, in other words, we get(1 << 1) + 0 = 10
in binary format. Similarlly, in the right child, we get(1 << 1) + 1 = 11
in binary format. -
In the main function, we start the helper function with
root
and0
. The base case is if theroot
is null, we return 0. After we update the current value, ifroot
is leaf, we return the updated current value. Else, we return the sum ofhelper(root.left, updatedCurVal)
andhelper(root.right, updatedCurVal)
.
Solution
1 |
|
Compare Version Numbers
Compare two version numbers version1 and version2.
If version1 > version2
return 1;
if version1 < version2
return -1;
otherwise return 0
.
You may assume that the version strings are non-empty and contain only digits and the .
character.
The .
character does not represent a decimal point and is used to separate number sequences.
For instance, 2.5
is not “two and a half” or “half way to version three”, it is the fifth second-level revision of the second first-level revision.
You may assume the default revision number for each level of a version number to be 0
. For example, version number 3.4
has a revision number of 3
and 4
for its first and second level revision number. Its third and fourth level revision number are both 0
.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Example 5:
1 |
|
Note:
-
Version strings are composed of numeric strings separated by dots
.
and this numeric strings may have leading zeroes. -
Version strings do not start or end with dots, and they will not be two consecutive dots.
Explanation
-
We can split the version string by
.
and convert the substring to integer and compare their version. -
If one string finish splitting, in other word, another string has more length, then we can make the short string as
0
by default and compare the long substring.
Solution
1 |
|
Bulls and Cows
You are playing the following Bulls and Cows game with your friend: You write down a number and ask your friend to guess what the number is. Each time your friend makes a guess, you provide a hint that indicates how many digits in said guess match your secret number exactly in both digit and position (called “bulls”) and how many digits match the secret number but locate in the wrong position (called “cows”). Your friend will use successive guesses and hints to eventually derive the secret number.
Write a function to return a hint according to the secret number and friend’s guess, use A
to indicate the bulls and B
to indicate the cows.
Please note that both secret number and friend’s guess may contain duplicate digits.
Example 1:
1 |
|
Example 2:
1 |
|
Note: You may assume that the secret number and your friend’s guess only contain digits, and their lengths are always equal.
Explanation
-
We can also solve this problem using one iteration. We will create an array
arr
of size 10 to count the increment of secretChar and decrement of guessChar. -
Loop through either one of the string, if both
secret
andguess
’s current character is the same, then we increasebull
. Else, we check ifarr[secretChar]
is less than 0, if true, then we increasecow
, and no matter it is less than 0 or geater than or equal to zero, we will increasearr[secretChar]
. Then, we check ifarr[guessChar]
is greater than 0, if true, then we increasecow
, and no matter it is greater than 0 or less than or equal to zero, we will decreasearr[guessChar]
. -
We do this because in the next iteration, if
arr[secretChar]
is less than 0, that means in the previous iterations,guessChar
appeared had appeared. Similarlly, ifarr[guessChar]
is greater than 0, that meanssecretChar
had appeared in the previous iterations.
Solution
1 |
|
Maximum Product Subarray
Given an integer array nums
, find the contiguous subarray within an array (containing at least one number) which has the largest product.
Example 1:
1 |
|
Example 2:
1 |
|
Explanation
-
We can solve this problem in one loop. In each iteration, we need to keep track of the maximum result ending here
curMax
, and minimum result ending herecurMin
. We can initializecurMax
,curMin
, and resultres
all be the first number of the array. -
Start from the second number, let say when we are on the
i
th number, if thei
th number is positive, then we use the current maximum number multiple by it in order to get the maximum result. If thei
th number is negative, then we use the current minimum number multiple by it to get the maximum result. Therefore, no matter thei
th number is positive or negative, we can get the maximum result bycurMax = max(nums[i], curMax * nums[i], curMin * nums[i])
. Similarlly, we can get the minimum result bycurMin = min(nums[i], curMax * nums[i], curMin * nums[i])
. After gettingcurMax
andcurMin
, we will update the resultres = max(res, curMax)
.
Solution
1 |
|
Combination Sum III
Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.
Note:
-
All numbers will be positive integers.
-
The solution set must not contain duplicate combinations.
Example 1:
1 |
|
Example 2:
1 |
|
Explanation
-
We can use backtracking to solve this problem. First we initialize a result list, a temperoary sublist. In the DFS helper function, we will pass these two lists and the
k
andn
, also the starting number, which is 1. -
Inside the helper function, the base case is if the temperoary sublist’s size is equal to
k
, then we also check ifn
is zero, then we add the sublist to the result list, and we will return immediatly. Another basecase is ifstart
is greater thann
, then we return immediately. If no base case satisfy, then we will loop start fromstart
to 9, recursivly calling the helper function, adding the iterative number to the sublist and update thestart = i + 1
andn = n - i
. After the helper function, remember remove the added number. Then it will add the next iterative number.
Solution
1 |
|
Insert Interval
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).
You may assume that the intervals were initially sorted according to their start times.
Example 1:
1 |
|
Example 2:
1 |
|
NOTE: input types have been changed on April 15, 2019. Please reset to default code definition to get new method signature.
Explanation
-
We need to draw a picture to illustrate this problem.
1
2
3
4original interval: - - - - - - - - - - - - - - - - - - - - - - added interval: - - - - - - - - - - - - - - - result: - - - - - - - - - - - - - - - - — - - - - - - - - - - - - - -
-
Iterate the original interval, if the interval’s end is greater than the added interval’s start, then they can merge, and we choose the smallest starting point between these two as the merge interval’s starting point. Then keep iterating, until the current interval’s start is greater than the added interval’s end, then we compare the previous interval with the added interval’s ending point and choose the greater ending point as the merge interval’s ending point.
1
2
3
4original interval: - - - - - - - - - - - - - - - - - - - - - added interval: - - - - result: - - - - - - - - - - - - - - - — - - - - - - - - -
-
In the above case, step2’s method also apply.
1
2
3
4original interval: - - - - - - - - - - added interval: - - - - result: - - - - - - - - - — - - - -
-
In the above case, we can initialize the merge inteval’s starting point and ending point as the added interval’s start and ending point.
1
2
3
4original interval: - - - - - - - - - added interval: - - - - - result: - - - - - - - - - - - - - -
-
In the above case, after iterate to the last interval and we haven’t find the merge interval, we can just added the added interval to the result and return the result.
Solution
1 |
|
House Robber
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
Example 1:
1 |
|
Example 2:
1 |
|
Constraints:
-
0 <= nums.length <= 100
-
0 <= nums[i] <= 400
Explanation
-
We can use dynamic programming to solve this problem.
-
Dynamic state is creating a one dimensional array
dp
.dp[i]
means the total maximum money when rob start from the first house to the indexi
house. -
Dynamic init. For example if
nums = [3, 2, 1, 5]
, then in index0dp[0] = 3
; then in index1,dp[1] = 3
because3 > 2
. -
Dyamic function. In index2, because we cannot rob the adjancent houses, so if we rob the current index2 house, then we cannot rob index1 house, in other word, if we rob index2, then
dp[2] = dp[0] + nums[2]
; if we don’t rob index2 house, thendp[2] = dp[1]
; so we can take the maximum of rob or not rob, which ismax(dp[0]+nums[2], dp[1])
. Therefore, dynamic function isdp[i] = max(dp[i-2] + nums[i], dp[i-1])
. -
Dynamic result is returning the last index of
dp
. -
Since
dp[i]
is only depends ondp[i-2]
anddp[i-1]
, we can store these two as variables and save space.
Solution
1 |
|
Week 3: September 15th - September 21st
Inorder Successor in BST II
Given a node
in a binary search tree, find the in-order successor of that node in the BST.
If that node has no in-order successor, return null
.
The successor of a node
is the node with the smallest key greater than node.val
.
You will have direct access to the node but not to the root of the tree. Each node will have a reference to its parent node. Below is the definition for Node
:
1 |
|
Follow up:
Could you solve it without looking up any of the node’s values?
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Example 5:
1 |
|
Constraints:
-
-10^5 <= Node.val <= 10^5
-
1 <= Number of Nodes <= 10^4
-
All Nodes will have unique values.
Explanation
-
To find the inorder successor, we have two cases.
-
The first case is if the node has right child, then the inorder successor is the node’s right child’s most left child node.
-
The second case is if the node doesn’t have right child, then the inorder success is the node’s parent node, and we will traverse up until the parent node has value greater than node’s value. Then the result is this parent node.
Solution 1
1 |
|
Explanation 2
- For the second case, we can achieve it by not comparing value. We will traverse up until the current node is the left child of the current node’s parent node. Then the result is the current node’s parent node.
Solution 2
1 |
|
Length of Last Word
Given a string s consists of upper/lower-case alphabets and empty space characters ' '
, return the length of last word (last word means the last appearing word if we loop from left to right) in the string.
If the last word does not exist, return 0.
Note: A word is defined as a maximal substring consisting of non-space characters only.
Example:
1 |
|
Explanation
-
We can solve it in one line. First trim the string and get its length
len
, then subtract 1 is the last index, then again subtract the last index of space of the trimmed string, which returns us the last word’s length. -
The second way is create a pointer that starts from the end, find the last character’s index, then set the result counter to 0. Increase 1 until the pointer poinits to empty space. Return the counter result.
Solution
1 |
|
Maximum XOR of Two Numbers in an Array
Given an integer array nums
, return the maximum result of nums[i] XOR nums[j]
, where 0 ≤ i ≤ j < n
.
Follow up: Could you do this in O(n)
runtime?
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Example 5:
1 |
|
Constraints:
-
1 <= nums.length <= 2 * 10^4
-
0 <= nums[i] <= 2^31 - 1
Explanation
-
We know that if
a ^ b = x
, thena ^ x = b
. -
For example to find the result’s highest bit. We put all numbers highest bit into a
HashSet
, then use 1 to XOR all numbers in theHashSet
. If the result is inside theHashSet
, that means the result’s highest bit is 1, not 0. In other words, we first assume the result’s highest bit is 1, then use 1 to XOR all numbers in theHashSet
. If1 ^ a = b
, andb
is in theHashSet
, that means two numbers from theHashSet
XOR can have result 1 (a ^ b = 1
), else no two numbers from theHashSet
is equals to 1, so the assumption is wrong, and the highest bit is 0. Similarlly, we can find the result’s second bit, third bit, etc. -
To find the result’s
n
bits, we put all numbers’ first leftn
bit into theHashSet
. Then we use the result’s first leftn-1
bit OR then
th bit which is 1 because we assume then
th bit is 1. Then use thistemp
result to XOR all numbers in the HashSet. If the XOR result is inside theHashSet
, thentemp
is the result’s firstn
bit result. -
For example, if input array is
[14, 11, 7, 2]
, its binary form is[1110, 1011, 0111, 0010]
, we can start from the fourth bit since know input has 4 bits. Soi=3
.1
2
3
41. i = 3, set = {1000, 0000} => max = 1000 2. i = 2, set = {1100, 1000, 0100, 0000} => max = 1100 because temp = 1000 | 0100, then temp XOR all numbers from the set. 3. i = 1, set = {1110, 1010, 0110, 0010} => max = 1100 4. i = 0, set = {1110, 1011, 0111, 0010} => max = 1100
Final answer is
1100 => 12
,1011 ^ 0111 = 1100(11 ^ 7 = 12)
.
Solution
1 |
|
Robot Bounded In Circle
On an infinite plane, a robot initially stands at (0, 0)
and faces north. The robot can receive one of three instructions:
-
"G"
: go straight 1 unit; -
"L"
: turn 90 degrees to the left; -
"R"
: turn 90 degress to the right.
The robot performs the instructions
given in order, and repeats them forever.
Return true
if and only if there exists a circle in the plane such that the robot never leaves the circle.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Note:
-
1 <= instructions.length <= 100
-
instructions[i]
is in{'G', 'L', 'R'}
Hint 1:
Calculate the final vector of how the robot travels after executing all instructions once - it consists of a change in position plus a change in direction.
Hint 2:
The robot stays in the circle iff (looking at the final vector) it changes direction (ie. doesn’t stay pointing north), or it moves 0.
Explanation
-
From the hint, we know that after executing all the instructions, if the current position is
(0, 0)
or the current direction is changed, then we have circle. -
First, we initialize the top, right, bottom, left direction diff
dirs
as[(0, 1), (1, 0), (0, -1), (-1, 0)]
, the direction indexd
is 0, and we initialize the current x, y position as(0, 0)
. -
If the current instruction is
'G'
, then we updatecurX += dirs[d][0]
andcurY += dirs[d][1]
. Else if the current instruction is'L'
, then we only need to update the direction index as(d + 3) % 4
because the left direction diff is at index 3 base on the initialization we defined. Else if the current instruction is'R'
, then we update the direction index as(d + 1) % 4
. -
After looping all instructions, if current position is
(0, 0)
or current direction index is different than the direction we started, that means there is circle, so we returnTrue
, else returnFalse
.
Solution
1 |
|
Best Time to Buy and Sell Stock
Say you have an array for which the ith element is the price of a given stock on day i.
If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit.
Note that you cannot sell a stock before you buy one.
Example 1:
1 |
|
Example 2:
1 |
|
Explanation
-
While we iterating the array, we need to keep track of the minimum element, and in each iteration, we subtract the minimum to get the current profit.
-
Also, each iteration we need to compare the maximum profit with the current profit.
Solution
1 |
|
Sequential Digits
An integer has sequential digits if and only if each digit in the number is one more than the previous digit.
Return a sorted list of all the integers in the range [low, high]
inclusive that have sequential digits.
Example 1:
1 |
|
Example 2:
1 |
|
Constraints:
10 <= low <= high <= 10^9
Hint 1:
Generate all numbers with sequential digits and check if they are in the given range.
Hint 2:
Fix the starting digit then do a recursion that tries to append all valid digits.
Explanation
-
First creating a string “123456789”, then use a sliding window logic to get the sequential number, then compare the sequential number with
low
andhigh
and add it to the result list. -
If number
low
has 4 digits, and numberhigh
has 5 digits, then we loop from window size 4 to window size 5 inclusive. Inside this for loop, we create an inner for loop to try all possible sequential number that has number ofwindowSize
digits. For example, if the current window size is 4, then the inner for loop will try1234
,2345
,3456
,4567
,5678
,6789
. If the current number is inside thelow
andhigh
range, then we add it to the result list.
Solution
1 |
|
Unique Paths III
On a 2-dimensional grid
, there are 4 types of squares:
-
1
represents the starting square. There is exactly one starting square. -
2
represents the ending square. There is exactly one ending square. -
0
represents empty squares we can walk over. -
-1
represents obstacles that we cannot walk over.
Return the number of 4-directional walks from the starting square to the ending square, that walk over every non-obstacle square exactly once.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Note:
1 <= grid.length * grid[0].length <= 20
Explanation
-
We can use DFS brute force to solve this problem. We find out every possible paths from starting square to ending square, once we reach the ending square, we compare the number of zero squares we visited with the total number of zero squares, if they match, then it means we walk over every zero square once.
-
First, we loop through every square to count the total number of zeros squares and record the starting square’s position.
-
We start the DFS helper function with the starting position
(startRow, startCol)
and the total number of zeroszeros
. Inside the DFS helper function, the base case are if current position is out of bound, we return 0; if current position is -1, we return 0; if the current position is the ending square, we check ifzeros
is 0, which mean we visit every zero squares, so we find one path and return 1 else return 0. If the current square is a zero square, then we subtract 1 fromzeros
. Next, we update the current position to number -1 to mark this position is visited, then recursively call the helper function with the current position’s 4 directions. ThetotalPaths
will be the 4 recursive function’s sum. Next, we need to backtrack this position and change -1 to its original number.
Solution
1 |
|
Car Pooling
You are driving a vehicle that has capacity
empty seats initially available for passengers. The vehicle only drives east (ie. it cannot turn around and drive west.)
Given a list of trips
, trip[i] = [num_passengers, start_location, end_location]
contains information about the i
-th trip: the number of passengers that must be picked up, and the locations to pick them up and drop them off. The locations are given as the number of kilometers due east from your vehicle’s initial location.
Return true
if and only if it is possible to pick up and drop off all passengers for all the given trips.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Constraints:
-
trips.length <= 1000
-
trips[i].length == 3
-
1 <= trips[i][0] <= 100
-
0 <= trips[i][1] < trips[i][2] <= 1000
-
1 <= capacity <= 100000
Hint 1:
Sort the pickup and dropoff events by location, then process them in order.
Explanation
- We can use brute force to solve this problem. Since the constraints
trips[i][2] <= 1000
, we can create an integer arraydistance[]
that has size 1001. Loop through thetrips[]
, in start location, we add the number of people indistance[startLocation]
; in end location, we subtract the number of people indistance[endLocation]
. Then loop through thedistance[]
, accumulate the count of number of peoplecnt += distance[i]
, ifcnt > capacity
, then we return false immediately. After the loop, return true.
Solution
1 |
|
Week 4: September 22nd - September 28th
Insert into a Sorted Circular Linked List
Given a node from a Circular Linked List which is sorted in ascending order, write a function to insert a value insertVal
into the list such that it remains a sorted circular list. The given node can be a reference to any single node in the list, and may not be necessarily the smallest value in the circular list.
If there are multiple suitable places for insertion, you may choose any place to insert the new value. After the insertion, the circular list should remain sorted.
If the list is empty (i.e., given node is null
), you should create a new single circular list and return the reference to that single node. Otherwise, you should return the original given node.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Constraints:
-
0 <= Number of Nodes <= 5 * 10^4
-
-10^6 <= Node.val <= 10^6
-
-10^6 <= insertVal <= 10^6
Explanation
-
First, if the list is empty, then we can create a node with the value equals to the
insertVal
and make itsnext
pointer pointing to itself. -
If the list is not empty, then we need to consider two cases.
-
First case is if the
insertVal
is in between the minimum node value and maximum node value. This can only happen if theinsertVal
is greater than the maximum node value orinsertVal
is less than the minimum node value. For example, from the problem’s example 1, the maximum node value is 4, the minimum node value is 1. If theinsertVal
is 5 or 0, theninsertVal
will be inserted between node 4 and node 1. -
Second case is the general case. For example, from the problem’s example 1, the
insertVal
is 2. We want to insert 2 in between node 1 and node 3. We can achieve this by creating two pointerspre
andcur
. We then check ifpre.val <= insertVal <= cur.val
and insert it after nodepre
.
-
Solution
1 |
|
Majority Element II
Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋
times.
Note: The algorithm should run in linear time and in O(1) space.
Example 1:
1 |
|
Example 2:
1 |
|
Hint 1:
How many majority elements could it possibly have? Do you have a better hint? Suggest it!
Explanation
-
Similar to 169. Majority Element, this time we need to find elements more than
n/3
times. There are must be at most two elements. If there are three elements that have more than $n/3$, then $3 * n/3 > 1$. So, we can use Moore Voting algorithm to find two most appeared numbers. -
After we find the two most appeared numbers
a
andb
, we also need to loop one more time of the array to check ifcountA
andcountB
are actually more thann/3
. Because it maybe only one element in the array have more than $n/3$ times.
Solution
1 |
|
Gas Station
There are N gas stations along a circular route, where the amount of gas at station i is gas[i]
.
You have a car with an unlimited gas tank and it costs cost[i]
of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.
Return the starting gas station’s index if you can travel around the circuit once in the clockwise direction, otherwise return -1.
Note:
-
If there exists a solution, it is guaranteed to be unique.
-
Both input arrays are non-empty and have the same length.
-
Each element in the input arrays is a non-negative integer.
Example 1:
1 |
|
Example 2:
1 |
|
Explanation
-
In order to loop all elements, total gas must equal or greater than total cost, then the
start
can exist. -
If we start from index 0, if current gas is equal or greater than current cost, then we can move forward. After we successfully move forward, we use the remaining gas plus the current gas minus the current cost to get the difference. If the difference is less than 0, that means we cannot start from any indexes between index 0 and current index inclusive. For example, we start from index 0, now when we are on index i, and
curGas + gas[i] - cost[i] < 0
, we know that after index i-1,curGas >= 0
, after index i-2,old_curGas >= 0
, etc. Any index beforei
will only bring positivecurGas
, so if at index i and the difference is negative, then thestart
cannot be any index between 0 andi
inclusive, so we updatestart = i + 1
. When finish looping, we returnstart
if the total gas is equal or greater than total cost.
Solution
1 |
|
Find the Difference
Given two strings s and t which consist of only lowercase letters.
String t is generated by random shuffling string s and then add one more letter at a random position.
Find the letter that was added in t.
Example:
1 |
|
Explanation
- We can also use XOR to solve this problem because if two same chacter XOR, it will become zero. If there’s only one character added, then the result will be that character.
Solution
1 |
|
Largest Number
Given a list of non negative integers, arrange them such that they form the largest number.
Example 1:
1 |
|
Example 2:
1 |
|
Note: The result may be very large, so you need to return a string instead of an integer.
Explanation
-
If we find out the most significatn digit by using
c = n / Math.pow(10, log10(n))
, then it’s complicated. -
We can convert each integer number to string, then make a comparator to compare two string’s concatnation and sort them.
-
Special case is if the first string starts with
0
like00
, we can return0
as the result.
Solution
1 |
|
Teemo Attacking
In LOL world, there is a hero called Teemo and his attacking can make his enemy Ashe be in poisoned condition. Now, given the Teemo’s attacking ascending time series towards Ashe and the poisoning time duration per Teemo’s attacking, you need to output the total time that Ashe is in poisoned condition.
You may assume that Teemo attacks at the very beginning of a specific time point, and makes Ashe be in poisoned condition immediately.
Example 1:
1 |
|
Example 2:
1 |
|
Note:
-
You may assume the length of given time series array won’t exceed 10000.
-
You may assume the numbers in the Teemo’s attacking time series and his poisoning time duration per attacking are non-negative integers, which won’t exceed 10,000,000.
Explanation
- We can use greedy method to solve this problem. If the difference between two adjacent time series is equals or greater than
duration
, we increase the result byduration
. Else, we increase the result by their difference.
Solution
1 |
|
Evaluate Division
You are given equations
in the format A / B = k
, where A
and B
are variables represented as strings, and k
is a real number (floating-point number). Given some queries
, return the answers. If the answer does not exist, return -1.0
.
The input is always valid. You may assume that evaluating the queries will result in no division by zero and there is no contradiction.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Constraints:
-
1 <= equations.length <= 20
-
equations[i].length == 2
-
1 <= equations[i][0], equations[i][1] <= 5
-
values.length == equations.length
-
0.0 < values[i] <= 20.0
-
1 <= queries.length <= 20
-
queries[i].length == 2
-
1 <= queries[i][0], queries[i][1] <= 5
-
equations[i][0], equations[i][1], queries[i][0], queries[i][1]
consist of lower case English letters and digits.
Hint 1:
Do you recognize this as a graph problem?
Explanation
- We can solve this problem using DFS. We create a variable
Map<String, HashMap<String, Double>> graph
. IfA/B=2.0
, then we havegraph[A][B] = 2.0
, andgraph[B][A] = 1.0/2.0
. If we knowA/B
andB/C
, then we can calculateA/C = A/B * B/C
. In other words,A / C = graph[A][B] * graph[B][C]
.
Solution
1 |
|
Subarray Product Less Than K
Your are given an array of positive integers nums.
Count and print the number of (contiguous) subarrays where the product of all the elements in the subarray is less than k.
Example 1:
1 |
|
Note:
-
0 < nums.length <= 50000
. -
0 < nums[i] < 1000
. -
0 <= k < 10^6
.
Hint 1:
For each j, let opt(j) be the smallest i so that nums[i] * nums[i+1] * … * nums[j] is less than k. opt is an increasing function.
Explanation
-
Since this is a subarray problem, we can think of using sliding window technique or two pointers (slow, fast pointers) technique. In this problem, we will use two pointers technique.
-
If
k
less than or equal to 1, we will return 0 since all elements in the input array are positive. We initializeslow = 0
andfast = 0
. Loopfast
from 0 to the last index of the input array, we can think offast
be the last element of the subarray,slow
be the first element of the subarray. In each iteration, we calculate the production byprod *= nums[fast]
. Ifprod < k
, we can count the number of subarray befast - slow + 1
. Else, whileprod >= k
, we need to updateprod /= nums[slow]
and moveslow
1 step forward.
Solution
1 |
|
Week 5: September 29th - September 30th
Word Squares
Given a set of words (without duplicates), find all word squares you can build from them.
A sequence of words forms a valid word square if the kth row and column read the exact same string, where 0 ≤ k < max(numRows, numColumns).
For example, the word sequence ["ball","area","lead","lady"]
forms a word square because each word reads the same both horizontally and vertically.
1 |
|
Note:
-
There are at least 1 and at most 1000 words.
-
All words will have the exact same length.
-
Word length is at least 1 and at most 5.
-
Each word contains only lowercase English alphabet
a-z
.
Example 1:
1 |
|
Example 2:
1 |
|
Explanation
-
Let’s analyze the problem’s first example. Assume the first word is
b a l l
, then what can the second word be? The answer is the second word must starts witha
. Now, assume we have the first word and second word, then what can the third word be? The answer is the third word must starts withl e
. Now, we notice that we need to quickly find a word that starts with certain characters or prefixes, the first thing pop up is using Trie. Also, this problem asks us to find different possiblities, we will use recursion to solve this kind of problem. -
First, we will create our Trie data structure. For the TrieNode class, in addition to the
TrieNode children[]
, we will also have a propertyList<String> startWith
to store a list of strings that have the same prefix. -
After we have our Trie setup, we need to think of how the recursion function’s signature look like. We will pass in the input
String[] words
, theTrie trie
, the result builderList<String> cur
, and the resultList<List<String>> res
. The basecase is if the result builder’s size is equal to the length of a word, then we can add this result builder into the result. Next, we will find theprefix
from the result builder, then use the trie to get a list of words that have thisprefix
. Then loop through this list of words, add it to the result builder, recursively call the helper function. After the recursive function, we need to backtrack by poping the added word from the result builder. -
Now we have our helper function setup. In the main function, we can loop through the input
String[] words
. We try each word as the first word of the word squares by adding it to the result builder and call the helper function. Also remember to backtrack the added word.
Source: https://youtu.be/TdX3EgW4_eM
Solution
1 |
|
Word Break
Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words.
Note:
-
The same word in the dictionary may be reused multiple times in the segmentation.
-
You may assume the dictionary does not contain duplicate words.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Explanation
-
We can also use dynamic programming to solve this problem. Dynamic state is a one dimensioanl array
dp
, and it has lengthdp[s.length()+1]
. It’s representd if thestring[0:i)
can be formed by the set or not. -
Dynamic init is
dp[0] = true
because if the string is empty, then it is inside the set. -
Dynamic function. For example,
string = "1234567"
, if we want to find if the string end at 5 (12345)dp[5]
is inside the set, previously, we should already finishdp[0], dp[1], dp[2], dp[3], dp[4]
, then we can loop through these dps, so ifdp[0]
is true and “12345” is inside the set, thendp[5]
is true; else ifdp[1]
is true and “2345” is inside the set thendp[5]
is true; else ifdp[2]
is true and “345” is inside the set, then we know dp[5] is true; In other word, we are using the previousdp[j]
to count whetherdp[i]
is true where j is from 0 to i-1. -
Dynamic result is the
dp[dp.length()-1]
which is the string from index 0 to the last character of the string.
Solution
1 |
|
First Missing Positive
Given an unsorted integer array, find the smallest missing positive integer.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Follow up:
Your algorithm should run in O(n) time and uses constant extra space.
Hint 1:
Think about how you would solve the problem in non-constant space. Can you apply that logic to the existing space?
Hint 2:
We don’t care about duplicates or non-positive integers
Hint 3:
Remember that O(2n) = O(n)
Explanation
-
If the input array length is 3, then the result can be 4 at maximum. For example:
1
2
3
4input = [1, 2, 3], result == 4. input = [1, 5, 3], result < 4. input = [3, 3, 3], result < 4. input = [-1, 3, 2], result < 4.
-
We can also use Cyclic Sort’s swapping method to solve this problem.
-
First start from the first number
nums[i]
in the array. Ifnums[i]
is within the range between 1 tonums.length
, and its valuenums[i]
is not equal to its corresponding indexnums[i]-1
’s value, in other words, ifnums[i] != nums[nums[i]-1]
, then we swap these two elements. Else, we increasei
. Repeat whilei
is less thannums.length
. -
Loop from the first number to the last. If the current index is not equals to current value’s corresponding index, in other words, if
nums[i]-1 != i
, that means we are missing the current index’s corresponding value which isi+1
.
Solution
1 |
|