Skip to content

Commit

Permalink
8 Mar 2022
Browse files Browse the repository at this point in the history
  • Loading branch information
infgeoax committed Mar 8, 2022
1 parent 492ea22 commit da58092
Show file tree
Hide file tree
Showing 16 changed files with 1,028 additions and 3 deletions.
48 changes: 48 additions & 0 deletions Algorithms/Interesting.Algorithms/morris.traversal.org
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#+title: Morris Traversal

A O(1) space, in-order, binary tree traversal algorithm.

* Tree node definition

#+begin_src C++
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
};
#+end_src

Given the root of the tree =root=, traverse the tree using constant space.

* Basic Idea

Modify a leaf node's right child to point to it's in-order successor.

#+begin_src C++
void morris(TreeNode* root) {
while(root) {
if (!root->left) {
visit(root);
root = root->right;
} else {
TreeNode* t = root->left;
while(t->right && t->right != root) t = t->right;
if (!t->right) {
// update t->right to point to root
t->right = root;
root = root->left;
} else {
// visited all root->left tree
visit(root);
t->right = nullptr;
root = root->right;
}
}
}
}
#+end_src

* Application
C++ destructor of a Tree may cause stackoverflow if the tree is not well balanced if we recursively call the destructor of each children.
Using Morris Traversal can eliminate this problem

51 changes: 48 additions & 3 deletions Algorithms/Leetcode/0042.trapping.rain.water.org
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,54 @@
right that's higher than that at position i. Now if we maintain a max height from both sides, and if they are both higher than position i, we know some water
can be trapped at position i, the amount is the minimum of the max heights minus the height at i.

One pointer move from left to right starting at 0, while the other from right to left starting at n - 1.
We also keep track of max heights the two pointers have seen.
One pointer move from left to right starting at 0, while the other from right to left starting at n - 1. We also keep track of max heights the two pointers
have seen.


Time Complexity: O(n), every height is accessed at most twice.

#+begin_src C++
int waterTrapped(vector<int>& heights) {
int n = heights.size();
int l = 0, r = n - 1;
int lmax = -1, rmax = -1;
int water = 0;
while (l < r) {
lmax = max(lmax, heights[l]);
rmax = max(rmax, heights[r]);
if (lmax < rmax) {
water += lmax - heights[l++];
} else {
water += rmax - heights[r--];
}
}
return water;
}
#+end_src


* Solution 2: min-stack
Using a stack to keep track of a decreasing sequence of heights, if the next height is higher than the top of the stack and the stack has more than one
element, then some water can be trapped in between current height and the one next to the top. How much? It's the number of heights between current and the
height next to the current.

Time complexity: O(n)
Space complexity: O(n), there could be at most n elements in the stack.

#+begin_src C++
int trap(vector<int>& heights) {
int n = heights.size();
int water = 0;
stack<int> stk;
for(int i = 0; i < n; ++i) {
int h = heights[i];
while(!stk.empty() && heights[stk.top()] < h) {
int top = stk.top(); stk.pop();
if (stk.empty()) break;
int blockHeight = min(heights[stk.top()], h) - heights[top];
water += blockHeight * (i - stk.top() - 1);
}
stk.push(i);
}
return water;
}
#+end_src
18 changes: 18 additions & 0 deletions Algorithms/Leetcode/0115.distinct.subsequences.org
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#+title: Distinct Subsequences

Given two strings s and t, return the number of distinct subsequences of s which equals t.

A string's subsequence is a new string formed from the original string by deleting some (can be none) of the characters without disturbing the remaining
characters' relative positions. (i.e., "ACE" is a subsequence of "ABCDE" while "AEC" is not).

The test cases are generated so that the answer fits on a 32-bit signed integer.

* Recursive call + memoization

Let \(f(i, j)\) be the number of distinct subsequences of s[i:] that equal t[j:], now what does \(f\) look like?

1. if \(j = length(t)\), the value is 1, as we have reached the end of string t.
2. if \(i = length(s)\), the value is 0, i.e. there's no more characters in s, but still some "unmatched" characters in t.
3. if \(s[i] = t[j]\), the value is \(f(i + 1, j + 1) + f(i + 1, j)\), that is the number of distinct subsequences of s[i+1:] that equal t[j+1:], plus the
number of distinct subsequences of s[i+1:] that equal t[j:]. That is, we can skip both, or we can only skip one character in s.
4. if \(s[i] != t[j]\), the value is \(f(i + 1, j)\), we cannot skip character in t, as we did not see a match.
9 changes: 9 additions & 0 deletions Algorithms/Leetcode/0128.longest.consecutive.sequence.org
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#+title: Longest Consecutive Sequence

Given an unsorted array of integers nums, return the length of the longest consecutive elements sequence.

You must write an algorithm that runs in O(n) time.

* Solution: hash set

If we keep a hashset that contains all elements from the input array, and we can test whether an element is in the set or not in roughly O(1) time.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#+title: Smallest Rectangle Enclosing Black Pixels

Given =mxn= binary matrix where =0= represents a white pixel and =1= a black pixel. Also given the location of one of the black pixels, =x= and =y=
find the area of the smallest rectangle that encloses all the black pxiels.

Time complexity must be less than =O(mn)=.

* Analysis

To Calculate the area, we need four numbers: (left, top) - (right, bottom)

- top: minimum of y
- bottom: maximum of y
- left: minimum of x
- right: maximum of x

- =O(mn)= is easy: DFS/BFS, and update the four numbers along the way.

- Is there a way to not go through all the nodes?
Loading

0 comments on commit da58092

Please sign in to comment.