In January, I spent so much time (almost a month) on calling AT&T and repaired my internet. It also turned out I needed to topup my phone because it exceeded 1 thousand miniutes limit. AT&T’s DSL is slow and not stable. Eventually switched to Comcast and finished setting up a cable.
Week 1: February 1st - February 7th
Squirrel Simulation
There’s a tree, a squirrel, and several nuts. Positions are represented by the cells in a 2D grid. Your goal is to find the minimal distance for the squirrel to collect all the nuts and put them under the tree one by one. The squirrel can only take at most one nut at one time and can move in four directions - up, down, left and right, to the adjacent cell. The distance is represented by the number of moves.
Example 1:
1 |
|
Note:
-
All given positions won’t overlap.
-
The squirrel can take at most one nut at one time.
-
The given positions of nuts have no order.
-
Height and width are positive integers. 3 <= height * width <= 10,000.
-
The given positions contain at least one nut, only one tree and one squirrel.
Hint 1:
Will Brute force solution works here? What will be its complexity?
Hint 2:
Brute force definitely won’t work here. Think of some simple solution. Take some example and make some observations.
Hint 3:
Will order of nuts traversed by squirrel is important or only first nut traversed by squirrel is important?
Hint 4:
Are there some paths which squirrel have to cover in any case? If yes, what are they?
Hint 5:
Did you notice only first nut traversed by squirrel matters? Obviously squirrel will choose first nut which will result in minimum distance.
Explanation
- Except the first nut that the squirrel pick, the distance for picking every other nuts and bring back to the tree is equal to
2 * getLen(tree, nuts[i])
. If the squirrel is in the tree, then the result is just2 * getLen(tree, nuts[i])
for everyi
. Now the squirrel is not in the tree, so it can save us some distance. For example,t
is the tree,x
is the squirrel,n
andm
are two nuts.
1 |
|
- If the squirrel picks
n
first, then it can save(5 - 1) * 2 - ((7 - 5) + (5 - 1)) = 2
distance. If the squirrel picksm
first, then it can save(9 - 1) * 2 - ((9-7) + (9-1)) = 6
distance. So picking the correct first nut matter.
Solution
1 |
|
Number of 1 Bits
Write a function that takes an unsigned integer and returns the number of ‘1’ bits it has (also known as the Hamming weight).
Note:
Note that in some languages such as Java, there is no unsigned integer type. In this case, the input will be given as a signed integer type. It should not affect your implementation, as the integer’s internal binary representation is the same, whether it is signed or unsigned.
In Java, the compiler represents the signed integers using 2’s complement notation. Therefore, in Example 3, the input represents the signed integer. -3
.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Constraints:
- The input must be a binary string of length
32
Follow up: If this function is called many times, how would you optimize it?
Explanation
-
Initialize
res
is 0. Get the right most bit, use AND, if the right most bit is 1, thenn&1
is 1; if the right most bit is 0, thenn&1
is 0. No matter is 1 or 0, we add it tores
. -
In each iteration, we right shift
n
by 1. -
Finally return
res
.
Solution
1 |
|
Trim a Binary Search Tree
Given the root
of a binary search tree and the lowest and highest boundaries as low
and high
, trim the tree so that all its elements lies in [low, high]
. Trimming the tree should not change the relative structure of the elements that will remain in the tree (i.e., any node’s descendant should remain a descendant). It can be proven that there is a unique answer.
Return the root of the trimmed binary search tree. Note that the root may change depending on the given bounds.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Example 5:
1 |
|
Constraints:
-
The number of nodes in the tree in the range
[1, 10^4]
. -
0 <= Node.val <= 10^4
-
The value of each node in the tree is unique.
-
root
is guaranteed to be a valid binary search tree. -
0 <= low <= high <= 10^4
Explanation
- We can use recursion to solve this problem. The base case is if the root is NULL, then we return NULL. Next we check if the root value is less than
low
, that means this root and its left subtree will be trimed, so we recursively check its right subtree. If the root value is greater thanhigh
, that means this root and its right subtree will be trimed, so we recursively check its left subtree. If the root value is in betweenlow
andhigh
, then we keep this root and we recursively check both its left and right subtree, and at the end return this root.
Solution
1 |
|
Linked List Cycle
Given head
, the head of a linked list, determine if the linked list has a cycle in it.
There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next
pointer. Internally, pos
is used to denote the index of the node that tail’s next
pointer is connected to. Note that pos
is not passed as a parameter.
Return true
if there is a cycle in the linked list. Otherwise, return false
.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Constraints:
-
The number of the nodes in the list is in the range
[0, 10^4]
. -
-10^5 <= Node.val <= 10^5
-
pos
is-1
or a valid index in the linked-list.
Follow up: Can you solve it using O(1)
(i.e. constant) memory?
Explanation
-
Both fast and slow pointers points to the head.
-
When fast pointer moves two steps, slow pointer move one step.
-
If fast pointer hits null, then no cycle; else if slow pointer and fast pointer point to the same node, then there’s cycle.
Solution
1 |
|
Longest Harmonious Subsequence
We define a harmonious array as an array where the difference between its maximum value and its minimum value is exactly 1
.
Given an integer array nums
, return the length of its longest harmonious subsequence among all its possible subsequences.
A subsequence of array is a sequence that can be derived from the array by deleting some or no elements without changing the order of the remaining elements.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Constraints:
-
1 <= nums.length <= 2 * 10^4
-
-10^9 <= nums[i] <= 10^9
Explanation
- We can think of each number from the input array is the minimum number, then we need to find how many maximum numbers from the array. The maximum number will just be the minimum number plus 1. When we know the frequency of minimum number and its corresponding maximum number’s frequency, then we know the result will just be frequency of minimum number plus frequency of maximum numbers.
Solution
1 |
|
Simplify Path
Given a string path
, which is an absolute path (starting with a slash '/'
) to a file or directory in a Unix-style file system, convert it to the simplified canonical path.
In a Unix-style file system, a period '.'
refers to the current directory, a double period '..'
refers to the directory up a level, and any multiple consecutive slashes (i.e. '//'
) are treated as a single slash '/'
. For this problem, any other format of periods such as '...'
are treated as file/directory names.
The canonical path should have the following format:
-
The path starts with a single slash
'/'
. -
Any two directories are separated by a single slash
'/'
. -
The path does not end with a trailing
'/'
.
The path only contains the directories on the path from the root directory to the target file or directory (i.e., no period '.'
or double period '..'
)
Return the simplified canonical path.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Constraints:
-
1 <= path.length <= 3000
-
path
consists of English letters, digits, period'.'
, slash'/'
or'_'
. -
path
is a valid absolute Unix path.
Explanation
-
First, we can split the input string by
"/"
. Then we can create a stack, iterate the array, if we see..
then we pop, otherwise we push the name of the directory to the stack. -
Special case is when we see the
.
or empty string, we ignore it. And at the end, the most inside directory name is at the top of the stack.
Solution
1 |
|
Binary Tree Right Side View
Given the root
of a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Constraints:
-
The number of nodes in the tree is in the range
[0, 100]
. -
-100 <= Node.val <= 100
Explanation 1
- In each level, we want to get the most right node. So we can use level-order traversal to solve this problem.
Solution 1
1 |
|
Explanation 2
-
We can also use recursion to solve this problem. First, we create a result list. Pass the result list, the tree root, and the level (depth) which initialize to 0 to the helper function.
-
In the helper function, the basecase is if the tree node is empty, we immediately return. If the size of the result list is equal to the depth, then we add the tree node value to the result list. Then we recursively call the helper function with the tree node’s right child first, then recursively call the helper function with the tree node’s left child.
Solution 2
1 |
|
Shortest Distance to a Character
Given a string s
and a character c
that occurs in s
, return an array of integers answer
where answer.length == s.length
and answer[i]
is the distance from index i
to the closest occurrence of character c
in s
.
The distance between two indices i
and j
is abs(i - j)
, where abs
is the absolute value function.
Example 1:
1 |
|
Example 2:
1 |
|
Constraints:
-
1 <= s.length <= 10^4
-
s[i]
andc
are lowercase English letters. -
It is guaranteed that
c
occurs at least once ins
.
Explanation
- We can solve this problem in 2 pass. First pass is looping from left to right and we only consider the distance to
c
wherec
is on the left side. Second pass is looping from right to left and now we take the minimum between the current (distance to left side) and the distance to the right sidec
, in other word,res[i] = min(res[i], res[i + 1] + 1
.
Solution
1 |
|
Week 2: February 8th - February 14th
Number of Distinct Islands
Given a non-empty 2D array grid
of 0’s and 1’s, an island is a group of 1
’s (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water.
Count the number of distinct islands. An island is considered to be the same as another if and only if one island can be translated (and not rotated or reflected) to equal the other.
Example 1:
1 |
|
Given the above grid map, return 1
.
Example 2:
1 |
|
Given the above grid map, return 3
.
Notice that:
1 |
|
and
1 |
|
are considered different island shapes, because we do not consider reflection / rotation.
Note: The length of each dimension in the given grid
does not exceed 50.
Explanation
- The difficult part about this problem is how to record the distinct island. We solve it by using a set of strings. Each string is represented by the direction of
1
s. In the main method, ifgrid[r][c]
equals to 1, then we enter the flood fill helper method and we append a string"o"
(origin) to the builder. Inside the helper method, if the top direction is 1, then we append a string"t"
(top) to the builder, similarily for right, down and left directions. After we finish checking the 4 directions, we also need to append a string"b"
(backtrack) to the builder because this can record how deep of the recursive helper method we backtrack. In the main method, after the helper method, we can append the string builder into our set. At the end, we can just returnset.size()
.
Solution
1 |
|
Peeking Iterator
Design an iterator that supports the peek
operation on a list in addition to the hasNext
and the next
operations.
Implement the PeekingIterator
class:
-
PeekingIterator(int[] nums)
Initializes the object with the given integer arraynums
. -
int next()
Returns the next element in the array and moves the pointer to the next element. -
bool hasNext()
Returnstrue
if there are still elements in the array. -
int peek()
Returns the next element in the array without moving the pointer.
Example 1:
1 |
|
Constraints:
-
1 <= nums.length <= 1000
-
1 <= nums[i] <= 1000
-
All the calls to
next
andpeek
are valid. -
At most
1000
calls will be made tonext
,hasNext
, andpeek
.
Follow up: How would you extend your design to be generic and work with all types, not just integer?
Hint 1:
Think of “looking ahead”. You want to cache the next element.
Hint 2:
Is one variable sufficient? Why or why not?
Hint 3:
Test your design with call order of peek()
before next()
vs next()
before peek()
.
Hint 4:
For a clean implementation, check out Google’s guava library source code.
Explanation
-
In java, we extends
iterator
interface, and it already hashasNext
andnext
methods. We can use these methods to help us, and we should add thepeek
method. -
In the constructor, we initialize an iterator
iter
equals to the argumentiterator
, and we cache thenex
integer value andhasNex
boolean value by checking ifiterator
hasNext and updatenex = iterator.next()
andhasNex = true
. Else we can just sethasNex = false
. So in thepeek
method, we just returnex
. In thehasNext
method, we just returnhasNex
. -
In the
next
method, saved the return valuenex
astemp
and return it at the end. Before we returntemp
, ifiter
hasNext, then we updatenex
toiter.next()
andhasNex
totrue
, which is same as the constructor.
Solution
1 |
|
Convert BST to Greater Tree
Given the root
of a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST.
As a reminder, a binary search tree is a tree that satisfies these constraints:
-
The left subtree of a node contains only nodes with keys less than the node’s key.
-
The right subtree of a node contains only nodes with keys greater than the node’s key.
-
Both the left and right subtrees must also be binary search trees.
Note: This question is the same as 1038: https://leetcode.com/problems/binary-search-tree-to-greater-sum-tree/
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Constraints:
-
The number of nodes in the tree is in the range
[0, 10^4]
. -
-10^4 <= Node.val <= 10^4
-
All the values in the tree are unique.
root
is guaranteed to be a valid binary search tree.
Explanation
- We can use in order traversal to solve this problem, but instead from the smallest element to the largest, we go from the largest to the smallest. Each time after we update the node’s value, we also update
sum
equals to that node’s value, so it’s accumulating the sum of all the right nodes.
Solution
1 |
|
Copy List with Random Pointer
A linked list of length n
is given such that each node contains an additional random pointer, which could point to any node in the list, or null
.
Construct a deep copy of the list. The deep copy should consist of exactly n
brand new nodes, where each new node has its value set to the value of its corresponding original node. Both the next
and random
pointer of the new nodes should point to new nodes in the copied list such that the pointers in the original list and copied list represent the same list state. None of the pointers in the new list should point to nodes in the original list.
For example, if there are two nodes X
and Y
in the original list, where X.random --> Y
, then for the corresponding two nodes x
and y
in the copied list, x.random --> y
.
Return the head of the copied linked list.
The linked list is represented in the input/output as a list of n nodes. Each node is represented as a pair of [val, random_index]
where:
-
val
: an integer representingNode.val
-
random_index
: the index of the node (range from0
ton-1
) that therandom
pointer points to, ornull
if it does not point to any node.
Your code will only be given the head
of the original linked list.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Constraints:
-
0 <= n <= 1000
-
-10000 <= Node.val <= 10000
-
Node.random
isnull
or is pointing to some node in the linked list.
Hint 1:
Just iterate the linked list and create copies of the nodes on the go. Since a node can be referenced from multiple nodes due to the random pointers, make sure you are not making multiple copies of the same node.
Hint 2:
You may want to use extra space to keep old node —> new node mapping to prevent creating multiples copies of same node.
Hint 3:
We can avoid using extra space for old node —> new node mapping, by tweaking the original linked list. Simply interweave the nodes of the old and copied list. For e.g.
1 |
|
Hint 4:
The interweaving is done using next pointers and we can make use of interweaved structure to get the correct reference nodes for random pointers.
Explanation 1
- We can solve this problem by creating a hashmap that maps the original node with its newly copied node. After creating a hashmap, loop from the
head
again, each iteration, we can easily set the current copied nodehm[curNode]
’snext
node tohm[curNode.next]
, and therandom
node tohm[curNode.random]
.
Solution 1
1 |
|
Explanation 2
-
In the above method, we used hashmap that costs extra space. This method can save space.
-
First, we copy a new node behind each node.
-
Then, we can assign new node’s random pointer by doing
cur.next.random = cur.random.next
. -
Finally, we can cut off the original node and copied node’s list.
Solution 2
1 |
|
Valid Anagram
Given two strings s and t , write a function to determine if t is an anagram of s.
Example 1:
1 |
|
Example 2:
1 |
|
Note:
You may assume the string contains only lowercase alphabets.
Follow up:
What if the inputs contain unicode characters? How would you adapt your solution to such case?
Explanation
-
If these two strings have different length, we can return
false
. -
Since all string characters are lower case, we can create an array with size 26 to store the frequency of the characters. In the first loop, we count the frequency of string
s
. -
In the second for loop of
t
, we decrease the array’s frequency. If any one element has negative frequency, we returnfalse
. -
Outside of the two for loop, we return
true
as the result.
Solution
1 |
|
Number of Steps to Reduce a Number to Zero
Given a non-negative integer num, return the number of steps to reduce it to zero. If the current number is even, you have to divide it by 2, otherwise, you have to subtract 1 from it.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Constraints:
0 <= num <= 10^6
Hint 1:
Simulate the process to get the final answer.
Explanation 1
- We can use brute force to solve this problem.
Solution 1
1 |
|
Explanation 2
-
We can also use bit manipulation to solve this problem.
-
We AND the
num
by 1, if the result is 1, that means it’s odd number, so we increase counter by 2; else if the result is 0, then it is even number, so we increase counter by 1. One corner case is whennum
equals to 1, it’s odd number, but this time we only increase the counter by 1.
Solution 2
1 |
|
Shortest Path in Binary Matrix
Given an n x n
binary matrix grid
, return the length of the shortest clear path in the matrix. If there is no clear path, return -1
.
A clear path in a binary matrix is a path from the top-left cell (i.e., (0, 0)
) to the bottom-right cell (i.e., (n - 1, n - 1)
) such that:
-
All the visited cells of the path are
0
. -
All the adjacent cells of the path are 8-directionally connected (i.e., they are different and they share an edge or a corner).
The length of a clear path is the number of visited cells of this path.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Constraints:
-
n == grid.length
-
n == grid[i].length
-
1 <= n <= 100
-
grid[i][j] is 0 or 1
Hint 1:
Do a breadth first search to find the shortest path.
Explanation
-
We can solve this problem using BFS.
-
First we check if the top left element and bottom right element is 1 or not, if it’s 1, then we return the result as -1 immediately. Next, we create a queue and push the top left position
[0, 0]
into the queue and mark it as visited by updatinggrid[0][0] = 2
. While the queue is not empty, we loop through all the current level’s elements and pop them. For the current popped element, we loop through its 8 neighbors, if the neighbor is 0, then we push it into the queue and mark it as visited. After we finishing looping the current level, we increase the level orres
by 1. When we pop the element from the queue, the pop element is located at the bottom right, then we returnres + 1
. Outside the queue, that means we don’t can’t go to bottom right, so we return -1.
Solution
1 |
|
Is Graph Bipartite?
There is an undirected graph with n
nodes, where each node is numbered between 0
and n - 1
. You are given a 2D array graph
, where graph[u]
is an array of nodes that node u
is adjacent to. More formally, for each v
in graph[u]
, there is an undirected edge between node u
and node v
. The graph has the following properties:
There are no self-edges (graph[u]
does not contain u
).
There are no parallel edges (graph[u]
does not contain duplicate values).
If v
is in graph[u]
, then u
is in graph[v]
(the graph is undirected).
The graph may not be connected, meaning there may be two nodes u
and v
such that there is no path between them.
A graph is bipartite if the nodes can be partitioned into two independent sets A
and B
such that every edge in the graph connects a node in set A
and a node in set B
.
Return true
if and only if it is bipartite.
Example 1:
1 |
|
Example 2:
1 |
|
Constraints:
-
graph.length == n
-
1 <= n <= 100
-
0 <= graph[u].length < n
-
0 <= graph[u][i] <= n - 1
-
graph[u]
does not containu
. -
All the values of
graph[u]
are unique. -
If
graph[u]
containsv
, thengraph[v]
containsu
.
Explanation 1
-
We can rephrase this problem to use two colors to color the graph, if there are two connected nodes have the same color, then we return false, else return true.
-
First, initialize an array
colors[]
to store all nodes’ color.0
means the node haven’t colored yet,1
means blue,-1
means red. We can loop through all the nodes, if the current node haven’t colored yet, then we color it, then we can use DFS to color its neighbor nodes with a different color. Inside the helper method, first we check if the node already has color, then we if this color is the same as the color we are going to color, then we return true, else we can return false immediately.
Solution 1
1 |
|
Explanation 2
- We can also use BFS to solve this problem.
Solution 2
1 |
|
Week 3: February 15th - February 21st
Kill Process
You have n
processes forming a rooted tree structure. You are given two integer arrays pid
and ppid
, where pid[i]
is the ID of the ith
process and ppid[i]
is the ID of the ith
process’s parent process.
Each process has only one parent process but may have multiple children processes. Only one process has ppid[i] = 0
, which means this process has no parent process (the root of the tree).
When a process is killed, all of its children processes will also be killed.
Given an integer kill
representing the ID of a process you want to kill, return a list of the IDs of the processes that will be killed. You may return the answer in any order.
Example 1:
1 |
|
Example 2:
1 |
|
Constraints:
-
n == pid.length
-
n == ppid.length
-
1 <= n <= 5 * 10^4
-
1 <= pid[i] <= 5 * 10^4
-
0 <= ppid[i] <= 5 * 10^4
-
Only one process has no parent.
-
All the values of
pid
are unique. -
kill
is guaranteed to be inpid
.
Explanation 1
- We need to kill the process
kill
and all its children process. We can solve it by creating a hashmap, key is the parent process id, value is a list of its children process id. Then we can use BFS to traverse all the children process under processkill
.
Solution 1
1 |
|
Explanation 2
- We can also use DFS recursively to record all the processes under id
kill
.
Solution 2
1 |
|
The K Weakest Rows in a Matrix
You are given an m x n
binary matrix mat
of 1
’s (representing soldiers) and 0
’s (representing civilians). The soldiers are positioned in front of the civilians. That is, all the 1
’s will appear to the left of all the 0
’s in each row.
A row i
is weaker than a row j
if one of the following is true:
-
The number of soldiers in row
i
is less than the number of soldiers in rowj
. -
Both rows have the same number of soldiers and
i < j
.
Return the indices of the k
weakest rows in the matrix ordered from weakest to strongest.
Example 1:
1 |
|
Example 2:
1 |
|
Constraints:
-
m == mat.length
-
n == mat[i].length
-
2 <= n, m <= 100
-
1 <= k <= m
-
matrix[i][j]
is either 0 or 1.
Hint 1:
Sort the matrix row indexes by the number of soldiers and then row indexes.
Explanation 1
- We can loop through every row of the matrix, for each row, we can use binary search to count the number of soldiers, then make a pair of
[rowIdx, numSoldiers]
. Next, we push this pair into an array or PriorityQueue that is sorted base on the problem description. At the end, we return the firstK
weakest rows.
Solution 1
1 |
|
Explanation 2
- We can also use a number
score
to represent both thenumSoldiers
androwIdx
. The formula isscore = numSoldiers * row + rowIdx
. We can getnumSoldiers = score / row
androwIdx = score % row
.
Solution 2
1 |
|
Letter Case Permutation
Given a string S, we can transform every letter individually to be lowercase or uppercase to create another string.
Return a list of all possible strings we could create. You can return the output in any order.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Constraints:
-
S
will be a string with length between1
and12
. -
S
will consist only of letters or digits.
Explanation 1
-
We can use BFS to solve this problem. First putting the input string to the queue first.
-
Loop
i
through each character of the input string. If the current character is a digit, then we continue. Else, we loopj
the current queue’s size, each time we poll the string out of the queue, then convert it to an array and update the indexi
character to lower case and append the updated string to the queue, similarlly, we also update the indexi
character to upper case and append the updated string to the queue. -
At the end, the queue contains all the permutations.
-
For example, if the input string is
abc
, then we have:
1 |
|
Solution 1
1 |
|
Explanation 2
-
Based on the above explanation, we can also use DFS to solve this problem. In the helper function, we pass the array representation of the input string, the result list, and the current index of the string. We want to use the index to mutate the
arr[index]
character. -
The base case is if the index is equal to the length of the array, we add the string representation of the array to the result list.
-
If
arr[index]
is a number, then we recursively call the helper function and passindex++
. Else, we mutate the index characterarr[index]
be lower case and pass to the helper function with updated index beindex++
, and mutate one more time be upper case and pass to the helper function.
Solution 2
1 |
|
Container With Most Water
Given n
non-negative integers a1, a2, ..., an
, where each represents a point at coordinate (i, ai)
. n
vertical lines are drawn such that the two endpoints of the line i
is at (i, ai)
and (i, 0)
. Find two lines, which, together with the x-axis forms a container, such that the container contains the most water.
Notice that you may not slant the container.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Constraints:
-
n == height.length
-
2 <= n <= 10^5
-
0 <= height[i] <= 10^4
Hint 1:
The aim is to maximize the area formed between the vertical lines. The area of any container is calculated using the shorter line as length and the distance between the lines as the width of the rectangle.
1 |
|
We can definitely get the maximum width container as the outermost lines have the maximum distance between them. However, this container might not be the maximum in size as one of the vertical lines of this container could be really short.
Hint 2:
Start with the maximum width container and go to a shorter width container if there is a vertical line longer than the current containers shorter line. This way we are compromising on the width but we are looking forward to a longer length container.
Explanation
-
We calculate the area by multipling the x-axis with the height, specifically the min height between the two bar.
-
When two bars at the beginning and at the end, the x-axis is the largest. So, we starts from here and use two pointers technique. We first calcualte the area with two bar at both end, then compare those two bars. If the left bar is shorter, we move it to the next bar, and compute the area. Else, if the right bar is shorter, then we move it to the previous bar and compute the area. Until the left pointer is greater or equal to the right pointer, we break out and return the maximum area.
Solution
1 |
|
Arithmetic Slices
An integer array is called arithmetic if it consists of at least three elements and if the difference between any two consecutive elements is the same.
- For example,
[1,3,5,7,9]
,[7,7,7,7]
, and[3,-1,-5,-9]
are arithmetic sequences.
Given an integer array nums
, return the number of arithmetic subarrays of nums
.
A subarray is a contiguous subsequence of the array.
Example 1:
1 |
|
Example 2:
1 |
|
Constraints:
-
1 <= nums.length <= 5000
-
-1000 <= nums[i] <= 1000
Explanation
-
[1,2,3]
has 1 arithmetic slice.[1,2,3,4]
has 3 arithmetic slices.[1,2,3,4,5]
has 6 arithmetic slices, which are:1
2
3
4
5
6
7``` len = 3: [1,2,3], [2,3,4], [3,4,5] len = 4: [1,2,3,4], [2,3,4,5] len = 5: [1,2,3,4,5] ```
-
When
len
is equals toarr.length
, then we have 1 arithmetic slice. Whenlen = arr.length-1
, then we have 2 arithmetic slice. Whenlen = arr.length-3
, then we have 3 arithmetic slices. Therefore, the total arithmetic slice will be1 + 2 + 3 + ... + n-2
. In other words,(n-1)(n-2)/2
.
Solution 1
1 |
|
Solution 2
1 |
|
Minimum Remove to Make Valid Parentheses
Given a string s of '('
, ')'
and lowercase English characters.
Your task is to remove the minimum number of parentheses ( '('
or ')'
, in any positions ) so that the resulting parentheses string is valid and return any valid string.
Formally, a parentheses string is valid if and only if:
-
It is the empty string, contains only lowercase characters, or
-
It can be written as
AB
(A
concatenated withB
), whereA
andB
are valid strings, or -
It can be written as
(A)
, whereA
is a valid string.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Constraints:
-
1 <= s.length <= 10^5
-
s[i]
is one of'('
,')'
and lowercase English letters.
Hint 1:
Each prefix of a balanced parentheses has a number of open parentheses greater or equal than closed parentheses, similar idea with each suffix.
Hint 2:
Check the array from left to right, remove characters that do not meet the property mentioned above, same idea in backward way.
Explanation
-
We need to remove the minimum number of parentheses to make the rest of parentheses valid, so we can think of this problem’s input doesn’t contain any letter.
-
We can verify a valid pair of parentheses by pushing left parenthese into the stack, if we see right parenthese, then we pop the stack, but If the stack is empty, then we know the current right parenthese is invalid, so we can increase the count for removing right parenthese. After we finish looping all characters of the string, if the stack is not empty, then the stack size is the count for removing left parenthese.
-
Now we have both the count for removing left parenthese and right parenthese. We can remove these extra left parenthese from right to left, and remove extra right parenthese from left to right.
Solution
1 |
|
Roman to Integer
Roman numerals are represented by seven different symbols: I
, V
, X
, L
, C
, D
and M
.
1 |
|
For example, 2
is written as II
in Roman numeral, just two one’s added together. 12
is written as XII
, which is simply X + II
. The number 27
is written as XXVII
, which is XX + V + II
.
Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII
. Instead, the number four is written as IV
. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX
. There are six instances where subtraction is used:
-
I
can be placed beforeV
(5) andX
(10) to make 4 and 9. -
X
can be placed beforeL
(50) andC
(100) to make 40 and 90. -
C
can be placed beforeD
(500) andM
(1000) to make 400 and 900.
Given a roman numeral, convert it to an integer.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Example 5:
1 |
|
Constraints:
-
1 <= s.length <= 15
-
s
contains only the characters('I', 'V', 'X', 'L', 'C', 'D', 'M')
. -
It is guaranteed that
s
is a valid roman numeral in the range[1, 3999]
.
Hint 1:
Problem is simpler to solve by working the string from back to front and using a map.
Explanation
-
Create a HashMap to map the roman character with its corresponding integer.
-
We can also loop through the roman string. If the current character’s corresponding integer is less than or equal to its previous character’s corresponding integer, then we add the current integer. For example VI, we add 5, add 1. In other words, (5+1=6).
-
Else if the current character’s corresponding integer is greater than its previous character’s corresponding integer, then we add the current integer and subtract the previous character’s corresponding integer multiple by 2. For example IV, we add 1, add 5, subtract 2x1. In other words, (1+5-2x1=4).
Solution
1 |
|
Broken Calculator
On a broken calculator that has a number showing on its display, we can perform two operations:
-
Double: Multiply the number on the display by 2, or;
-
Decrement: Subtract 1 from the number on the display.
Initially, the calculator is displaying the number X
.
Return the minimum number of operations needed to display the number Y
.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Note:
-
1 <= X <= 10^9
-
1 <= Y <= 10^9
Explanation
-
We can think of this problem by given Y and finding X by using /2 and +1. The reason is going from X to Y is not deterministic, because one can choose to x2, or -1 first and then x2. However, going from Y to X is deterministic, because we cannot do /2 when Y is an odd number. Therefore, whenever Y is an odd number, the only thing we can do is +1 and then /2. Therefore, going from Y to X is straightforward.
-
Another explanaion is for X < Y, if we start from X, then we don’t have a clue how should we pick -1 or x2, but if we start from Y, and look at it odd-eveness, then we would have a clue.
- If Y is odd, then the last operation must be -1, no other approaches.
- Hence from Y to find X, we will +1 when Y is odd.
- If Y is even, then we have two choices: -1 or x2.
- To get last Y from last second Y2, we have two ways: Y2 * 2 or Y2 * 2 - 1 - 1 * Y2 * 2 -1 - 1 = (Y2-1) * 2, and (Y2-1) * 2 can save us one operation. * Hence from Y to find X, we will always pick /2 when Y is even.
Solution
1 |
|
Week 4: February 22nd - February 28th
Find the Celebrity
Suppose you are at a party with n
people (labeled from 0
to n - 1
), and among them, there may exist one celebrity. The definition of a celebrity is that all the other n - 1
people know him/her, but he/she does not know any of them.
Now you want to find out who the celebrity is or verify that there is not one. The only thing you are allowed to do is to ask questions like: “Hi, A. Do you know B?” to get information about whether A knows B. You need to find out the celebrity (or verify there is not one) by asking as few questions as possible (in the asymptotic sense).
You are given a helper function bool knows(a, b)
which tells you whether A knows B. Implement a function int findCelebrity(n)
. There will be exactly one celebrity if he/she is in the party. Return the celebrity’s label if there is a celebrity in the party. If there is no celebrity, return -1
.
Example 1:
1 |
|
Example 2:
1 |
|
Constraints:
-
n == graph.length
-
n == graph[i].length
-
2 <= n <= 100
-
graph[i][j]
is0
or1
. -
graph[i][i] == 1
Follow up: If the maximum number of allowed calls to the API knows
is 3 * n
, could you find a solution without exceeding the maximum number of calls?
Hint 1:
The best hint for this problem can be provided by the following figure:
Hint 2:
Well, if you understood the gist of the above idea, you can extend it to find a candidate that can possibly be a celebrity. Why do we say a “candidate”? That is for you to think. This is clearly a greedy approach to find the answer. However, there is some information that would still remain to be verified without which we can’t obtain an answer with certainty. To get that stake in the ground, we would need some more calls to the knows API.
Explanation 1
- If
knows(i, j) == true || knows(j, i) == false
then we knowi
is not a celebrity, else we knowj
is not a celebrity. We can use two for loops to try every pair of persion and find out the celebrity.
Solution 1
1 |
|
Explanation 2
- Initialize the celebrity
res = 0
. Loop through every personi
, ifknows(res, i) == true
, then we updateres = i
. Since we have maximum one celebrity,res
maybe the celebrity. After this first loop, we knowres
doesn’t know every personi
that is greater thanres
. Next we need to verify ifres
is the celebrity. We can check two groups of people. First group is person 0 to personres-1
inclusive. Second group is personres+1
ton-1
inclusive. For the first group of people, we need to check ifknows(res, i) == true
orknows(i, res) == false
, thenres
is not celebrity. Second group is fori
greater thanres
. Since we knowknows(res, i) == false
from the first for loop, we can now only check ifknows(i, res) == false
, thenres
is not celebrity. After checking both group, thenres
is the celebrity.
Solution 2
1 |
|
Longest Word in Dictionary through Deleting
Given a string s
and a string array dictionary
, return the longest string in the dictionary that can be formed by deleting some of the given string characters. If there is more than one possible result, return the longest word with the smallest lexicographical order. If there is no possible result, return the empty string.
Example 1:
1 |
|
Example 2:
1 |
|
Constraints:
-
1 <= s.length <= 1000
-
1 <= dictionary.length <= 1000
-
1 <= dictionary[i].length <= 1000
-
s
anddictionary[i]
consist of lowercase English letters.
Explanation
- We can use the isSubsequence method from Longest Uncommon Subsequence II to check if the iterated string is the subsequence of string
s
. So we iterate the strings from the list, if the current iterated string is the subsequence and its length is longer thanres
, we updateres
be the iterated string.
Solution
1 |
|
Search a 2D Matrix II
Write an efficient algorithm that searches for a target
value in an m x n
integer matrix
. The matrix
has the following properties:
-
Integers in each row are sorted in ascending from left to right.
-
Integers in each column are sorted in ascending from top to bottom.
Example 1:
1 |
|
Example 2:
1 |
|
Constraints:
-
m == matrix.length
-
n == matrix[i].length
-
1 <= n, m <= 300
-
-10^9 <= matix[i][j] <= 10^9
-
All the integers in each row are sorted in ascending order.
-
All the integers in each column are sorted in ascending order.
-
-10^9 <= target <= 10^9
Explanation
-
We notice that the bottom left number is special. All numbers above the bottom left number are less than it; all numbers on the right side of the bottom left number are greater than it. Similar to the top right number.
-
We can choose either bottom left or top right number to compare with the target value. For example, if we choose bottom left number
num[r][c]
, if the target is smaller, then we make the new bottom left number to be thenum[r-1][c]
; else if the target is greater, then we make the new bottom left number to benum[r][c+1]
; else if the target is equal to the bottom left number, we returntrue
. If row and column are out of bound, we returnfalse
.
Solution
1 |
|
Score of Parentheses
Given a balanced parentheses string S
, compute the score of the string based on the following rule:
-
()
has score 1 -
AB
has scoreA + B
, where A and B are balanced parentheses strings. -
(A)
has score2 * A
, where A is a balanced parentheses string.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Note:
-
S
is a balanced parentheses string, containing only(
and)
. -
2 <= S.length <= 50
Explanation 1
- We can use a stack to hold the scores for each depth. Iterate the string, if the current character is
(
, then we push 0 into the stack because we start a new depth and this depth’s score is 0. If the current character is)
, then the current depth’s score will bemax(1, 2 * curDepthScore)
, also the current depth score need to plus its previous depth’s score. For example( ( ) ( ) . )
, when we are on index 4, the current depth will be1 + 1 = 2
. That’s also the reason we add 0 as the previous depth’s score into the stack before we iterate the string.
Solution 1
1 |
|
Explanation 2
- We keep track of the depth. If we meet
(
, we increase the depth by 1. If we meet)
, we decrease the depth by 1. If we meet( )
, then we know the outside depth, so we increase the result by 2 to the powe of outsideDepth. For example,( ( ) . )
. When we are on index 2, the outside depth is 1, so we increase the result by2^1
. Another example is( ( ) ( ) )
, when we are on index 2, outside depth is 1, so we increase result by2 ^ 1
, when we are on index 4, outside depth is 1, so we increase result by2 ^ 1
, so total result is 4.
Solution 2
1 |
|
Shortest Unsorted Continuous Subarray
Given an integer array nums
, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order.
Return the shortest such subarray and output its length.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Constraints:
-
1 <= nums.length <= 10^4
-
-10^5 <= nums[i] <= 10^5
Follow up: Can you solve it in O(n)
time complexity?
Explanation
-
We want to find the subarray’s
left
andright
end index. -
We can create
max
equals to the first number of the input array, and we createmin
equals to the last number of the input array. Start loopingi
from the second number, updatemax
equals to the maximum ofmax
andnums[i]
. After update, ifmax
is greater thannums[i]
, thenright = i
. Similarlly, updatemin
to be the minimum ofmin
andnums[nums.length-1-i]
. Ifmin
is less thannums[nums.length-1-i]
, then we haveleft = nums.length-1-i
. Notice thatright
is moving to the right,left
is moving to theleft
. At the end, we get the subarray’s beginning idexleft
and ending indexright
. Then we can get its length. -
For example, think of the input array is
[4, 3, 2, 1]
. Initially,max = 4
,min = 1
.
Solution
1 |
|
Validate Stack Sequences
Given two sequences pushed
and popped
with distinct values, return true
if and only if this could have been the result of a sequence of push and pop operations on an initially empty stack.
Example 1:
1 |
|
Example 2:
1 |
|
Constraints:
-
0 <= pushed.length == popped.length <= 1000
-
0 <= pushed[i], popped[i] < 1000
-
pushed
is a permutation ofpopped
. -
pushed
andpopped
have distinct values.
Explanation
- We can use brute force to solve this problem. Loop through the
pushed
array. Inside thepushed
array, we pushpushed[i]
into a stack. While the top of the stack is equal topopped[popIdx]
, then we pop the stack and increasepopIdx
. At the end, ifpopIdx
is equal to the length ofpopped[]
, we return true, else return false.
Solution
1 |
|
Divide Two Integers
Given two integers dividend
and divisor
, divide two integers without using multiplication, division, and mod operator.
Return the quotient after dividing dividend
by divisor
.
The integer division should truncate toward zero, which means losing its fractional part. For example, truncate(8.345) = 8
and truncate(-2.7335) = -2
.
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, assume that your function returns 2^31 − 1
when the division result overflows.
Example 1:
1 |
|
Example 2:
1 |
|
Example 3:
1 |
|
Example 4:
1 |
|
Constraints:
-
-2^31 <= dividend, divisor <= 2^31 - 1
-
divisor != 0
Explanation
-
We can use bit operation to solve this problem.
-
Initialize
res = 0
. While divident is greater or equal than the divisor, we left shift the divisor. Each time we left shift the divisor, we multiple by 2 and add to theres
. For example, if thedivident
is 32 anddivisor
is 3. Left shift one time,divisor
becomes 6; left shift two time, it becomes 12; left shift three times, it becomes 24; left shift four times, it becomes 48. Now thedivisor
is greater than thedivident
, so we need left shift 3 times to keep thedivisor
less thandivident
, and theres = 2^3=8
. If we left shift 3 times, thedivisor
is 24, we usedivident
subtract it, we get the newdivident = 32-24 = 8
. Repeat the same step withdivident=8
anddivisor=3
. Now, we can only left shift 1 times since3*2=6<8
, andres
will be2^1=2
, so we getres = 8+2 = 10
. -
JavaScript bitwise is for signed 32-bit, so instead of
while ((base << 1) <= dividend)
, we dowhile (base <= (dividend >> 1))
.
Solution
1 |
|
Maximum Frequency Stack
Design a stack-like data structure to push elements to the stack and pop the most frequent element from the stack.
Implement the FreqStack
class:
-
FreqStack()
constructs an empty frequency stack. -
void push(int val)
pushes an integerval
onto the top of the stack. -
int pop()
removes and returns the most frequent element in the stack.- If there is a tie for the most frequent element, the element closest to the stack’s top is removed and returned.
Example 1:
1 |
|
Constraints:
-
0 <= val <= 10^9
-
At most
2 * 10^4
calls will be made topush
andpop
. -
It is guaranteed that there will be at least one element in the stack before calling
pop
.
Explanation
- First, we need to maintain a frequency map, the key is the number, the value is its frequency. Since we are popping the max frequency number, so we need to maintain a
maxFrequency
value. To keep track of all numbers that have the same frequency, we can create a hashmapfreqSt
, the key is the frequency, the value is a stack of numbers that has that frequency, so that the latest number is always on the top of that stack.
Solution
1 |
|