Sunday, February 24, 2019

LeetCode 98. Validate Binary Search Tree




Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
  • 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.
Example 1:
Input:
    2
   / \
  1   3
Output: true
Example 2:
    5
   / \
  1   4
     / \
    3   6
Output: false
Explanation: The input is: [5,1,4,null,null,3,6]. The root node's value
             is 5 but its right child's value is 4.

















LeetCode 200. Number of Islands.java



Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
Example 1:
Input:
11110
11010
11000
00000

Output: 1
Example 2:
Input:
11000
11000
00100
00011

Output: 3












LeetCode 872. Leaf-Similar Trees.java



Consider all the leaves of a binary tree.  From left to right order, the values of those leaves form a leaf value sequence.
For example, in the given tree above, the leaf value sequence is (6, 7, 4, 9, 8).
Two binary trees are considered leaf-similar if their leaf value sequence is the same.
Return true if and only if the two given trees with head nodes root1 and root2 are leaf-similar.













LeetCode 559. Maximum Depth of N-ary Tree.java




Given a n-ary tree, find its maximum depth.
The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
For example, given a 3-ary tree:


We should return its max depth, which is 3.

Note:
  1. The depth of the tree is at most 1000.
  2. The total number of nodes is at most 5000.















LeetCode 897. Increasing Order Search Tree.java



Given a tree, rearrange the tree in in-order so that the leftmost node in the tree is now the root of the tree, and every node has no left child and only 1 right child.
Example 1:
Input: [5,3,6,2,4,null,8,1,null,null,null,7,9]

       5
      / \
    3    6
   / \    \
  2   4    8
 /        / \ 
1        7   9

Output: [1,null,2,null,3,null,4,null,5,null,6,null,7,null,8,null,9]

 1
  \
   2
    \
     3
      \
       4
        \
         5
          \
           6
            \
             7
              \
               8
                \
                 9  
Note:
  1. The number of nodes in the given tree will be between 1 and 100.
  2. Each node will have a unique integer value from 0 to 1000.









Saturday, February 23, 2019

LeetCode 101. Symmetric Tree.java



For example, this binary tree [1,2,2,3,4,4,3] is symmetric:
    1
   / \
  2   2
 / \ / \
3  4 4  3
But the following [1,2,2,null,3,null,3] is not:
    1
   / \
  2   2
   \   \
   3    3
Note:
Bonus points if you could solve it both recursively and iteratively.












LeetCode 104. Maximum Depth of Binary Tree




Example:
Given binary tree [3,9,20,null,null,15,7],
    3
   / \
  9  20
    /  \
   15   7
return its depth = 3.















LeetCode 339. Nested List Weight Sum


https://leetcode.com/problems/nested-list-weight-sum/submissions/

Example 1:
Input: [[1,1],2,[1,1]]
Output: 10 
Explanation: Four 1's at depth 2, one 2 at depth 1.
Example 2:
Input: [1,[4,[6]]]
Output: 27 
Explanation: One 1 at depth 1, one 4 at depth 2, and one 6 at depth 3; 1 + 4*2 + 6*3 = 27.

Saturday, February 16, 2019

LeetCode Weekly 124 - 995. Minimum Number of K Consecutive Bit Flips



995. Minimum Number of K Consecutive Bit Flips
In an array A containing only 0s and 1s, a K-bit flip consists of choosing a (contiguous) subarray of length K and simultaneously changing every 0 in the subarray to 1, and every 1 in the subarray to 0. Return the minimum number of K-bit flips required so that there is no 0 in the array. If it is not possible, return -1.









LeetCode Weekly 124 - 994. Rotting Oranges



994. Rotting Oranges
In a given grid, each cell can have one of three values: the value 0 representing an empty cell; the value 1 representing a fresh orange; the value 2 representing a rotten orange. Every minute, any fresh orange that is adjacent (4-directionally) to a rotten orange becomes rotten. Return the minimum number of minutes that must elapse until no cell has a fresh orange. If this is impossible, return -1 instead.








LeetCode Weekly 124 - 993. Cousins in Binary Tree



993. Cousins in Binary Tree 
 In a binary tree, the root node is at depth 0, and children of each depth k node are at depth k+1. Two nodes of a binary tree are cousins if they have the same depth, but have different parents. We are given the root of a binary tree with unique values, and the values x and y of two different nodes in the tree. Return true if and only if the nodes corresponding to the values x and y are cousins.









Wednesday, January 30, 2019

Advanced Data Structure — UnionFind. - Find the big brother.


So you decided to take it one step further, huh? Instead of settling with Array and maybe LinkedList.
Although there’s nothing wrong just knowing the basic ones, you still can be a solid developer.
But if you ever want to be a engineer, let’s dive in:

Step 0. Why? (Skip to Step 1 if you are a professional)
What exactly is UnionFind and why do we need it?
Remember Audible and Amazon, eh?
Now who’s the boss?
Yes! Audible belongs to Amazon.
Ok this sounds far too simple, we can just get a HashMap, and just point the Audible to its parent.
Well well well, imagine you are in a system design and need to point thousands of employees to their parent, hmm?
Oh and make it more challenging let’s say the companies are merging and selling all the time.
Great! You agreed we need something efficient and professional.

Step 1. How?
So for professionals I am telling you outright that UnionFind actually is tree.
You were right, using a HashMap or Array would do the job but we need a little delicate path compression and trust me this data structure is full of traps that you can make it full of bugs easily if careless, or even just tired.
For the sake of brevity we are using a simple primitive Java array. (You can swap it with a HashMap easily).
  • 1.1. Constructor
We are simply pointing everybody to himself. Meaning everyone is a disconnected dot. Audible belongs to Audible meaning it is not yet acquired by any other company.
public ConnectingGraph_589(int n) {
    // do intialization if necessary
    father = new int[n + 1];
    for (int i = 1; i <= n; i++) {
        father[i] = i;
    }
}
  • 1.2. Connect
Connect two companies together. e.g. pointing Audible as the son of Amazon. Meaning Amazon acquires Audible.
public void connect(int a, int b) {
    // write your code here
    int rootA = find(a);
    int rootB = find(b);
    if (rootA != rootB) {
        father[rootA] = rootB;
    }
}
  • 1.3. Query
Check if the two companies belong to the same corporation.
This means returning true if Audible and Amazon has the same BIG brother — Amazon.
Or let’s say returning true if Nokia and Microsoft has the same BIG brother — the MS.
public boolean query(int a, int b) {
    // write your code here
    return find(a) == find(b);
}
  • 1.4 Find
This is the best part of the data structure in that you recursively find the BIG brother and update every children in the meanwhile.
private int find(int x) {
    if (father[x] == x) {
        return x;
    } else {
        return father[x] = find(father[x]);
    }
}

Last Step, show me the code:
public class ConnectingGraph_589 {
    private int[] father;

    /*
     * @param n: An integer
     */
    public ConnectingGraph_589(int n) {
        // do intialization if necessary
        father = new int[n + 1];
        for (int i = 1; i <= n; i++) {
            father[i] = i;
        }
    }

    /*
     * @param a: An integer
     * @param b: An integer
     * @return: nothing
     */
    public void connect(int a, int b) {
        // write your code here
        int rootA = find(a);
        int rootB = find(b);
        if (rootA != rootB) {
            father[rootA] = rootB;
        }
    }

    /*
     * @param a: An integer
     * @param b: An integer
     * @return: A boolean
     */
    public boolean query(int a, int b) {
        // write your code here
        return find(a) == find(b);
    }

    private int find(int x) {
        if (father[x] == x) {
            return x;
        } else {
            return father[x] = find(father[x]);
        }
    }
}
For more algorithms feel free to check out my Github https://github.com/oliverwreath/JiuZhang.git

Saturday, January 26, 2019

Ch4 BFS - Bootstrap your algorithms.

Now as it is known to all, the BFS can be easily implemented with the help of a Queue, or more so a FIFO data structure.

But much less known to all, the BFS has quite a few variations of implementation.
For starters, there's two Queue implementation and there's one Queue.
You can use a level counter, or you can simply use a dummyNode.

Alright so here's just one way of going about doing it.

PS: If you are using Java 8 and love succinct code, just use offer and poll methods as they don't invoke type conversion like the addFirst, addLast do. Which can look quite unappreciated.



Ch5 DFS - Bootstrap your algorithms.

As we all know BFS and DFS are the famous two pillars of the Searching algorithms.

Now as we all know BFS can be easily accomplished with a simple Queue. Or let's say a FIFO data structure.

But the DFS remains a tricky one, for we actually usually keep the main function concise and just call a beefy helper function to get it done.

Of course somebody will raise their hand and say "Why not just use recursion?"
Baby, recursion and iterations are not algorithms themselves, however they remains two different styles of implementing the same algorithms.

Now talk is cheap, show me the code:


Tuesday, January 22, 2019

Spring Boot Environment Switch Made Easy

Spring Boot Environment Switch Made Easy

Tired of changing the *.properties file spring.profiles.active=dev to prod every single time before deployment? 
You are NOT alone! 
It is OK to stand up and say, enough! 
application-dev.properties

Step 3 — Setup the Production environment to automatically call PROD profile.

spring.profiles.active=prod
That’s right baby! I go through a bunch of documents and StackOverFlow posts just to find out we only need one simply setting. 
PS: Depending on your AWS Beanstalk environment version, the old posts suggesting SPRING_PROFILES_ACTIVE(Linux environment style) didn’t work. The reason being Amazon aws apparently prefer this style and change them overnight. Yay thanks to me now you probably just dodge a bullet of half and hour. 

Step 2 — Setup the Development environment to automatically call DEV profile. 

The key is to set the JVM options: -Dspring.profiles.active=dev
-Dspring.profiles.active=dev
PS: there could be a pitfall depending on your IDE, as I was caught off-guard seeing all the tests failed! But it turns out that I need to set the JVM options for every single one of the tests too! 
-Dspring.profiles.active=dev

Step 1 — Setup a couple of properties file for each and every environment.

  • Keep your common settings, just leave them right where they are. 
  • Migrate dev settings (e.g.Turn on hibernate sql print; Turn off the view engine cache to see instant change as you write your code) to the application-dev.properties. 
  • Migrate prod settings (e.g. Turn on all sort of caches. Jack up the number of connections in pool.) to the application-prod.properties.

Alright, now you are all set. 
Feel free to comment below share your thoughts experience.
For more technical articles feel free to follow.