Thursday, May 30, 2019

450. Delete Node in a BST 2019 practice

Here is the link.


It is my practice in 2019. I have to work on so many algorithms, one thing I can do is to share more content on this practice, and also work on my patience. One thing I can do is to go over example tree, and work on the example more carefully, so that next time I will not miss an edge case.

To be a good engineer, I have to learn how to work on the example tree, go over the tree at least once to show myself how to approach the problem. I am not afraid to implement any idea I may come out; only thing I have to work on is to pay attention to edge case, do not rely on online judge to remind me my mistakes.

Here is the copy of content in Leetcode discuss. 

It is one of mock interview algorithms. I spent first 10 minutes to draw a tree and then figure out the solution by myself.
To be a good problem solver, I have to work on my patience and draw some example tree, and work on the edge case carefully. Here is the tree I like to present and I explain how to solve the problem in multiple steps.
Given root node with value 6, and key 4, I need to find the node with value 4, and then search it's left subtree to find maximum value node first.
image
Given root node with value 6, and key 4, I worked on the above tree, go to node 4 left subtree and try to find maximum value in left subtree. I find node 3 and it's parent node, and then node 4's value will be updated to 3, and node 3's parent will have right child set as node's left child.
I ran the code against online judge, and then I found out that I missed another case. What if the node 4's left child is largest node in left subtree.
I need more patience and think about more carefully in order to solve the problem in shortest time.
Here are hightlights of my solution:
  1. Since the root node can be the node with key value, and the tree maybe is the one with one node. So I create a dummy node and make root node as its left child;
  2. Use binary search to search key value in binary search tree, either root node has the value key, or go to left or right to search the node;
  3. Use step 2 to find node with key value first, and work on the case if node with key value has left child;
  4. Write a while loop to find rightmost node in left subtree, and also keep parent node;
  5. Set key value node with rightmost node's value
  6. reconnect rightmost node's parent node's right child, remove rightmost node from the tree
  7. Work on the right subtree case
  8. Find out that I missed the edge case - step 4, left child of node value 4 is the largest node in left subtree
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left;
 *     public TreeNode right;
 *     public TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    /// <summary>
        /// binary search the node
        /// binary search tree
        /// </summary>
        /// <param name="root"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public TreeNode DeleteNode(TreeNode root, int key)
        {
            if (root == null)
                return root;

            TreeNode parentNode = new TreeNode(1);
            parentNode.left = root; 
             
            traverseTree(root, parentNode, true, key);

            return parentNode.left; 
        }

        /// <summary>
        /// May 30, 2019
        /// </summary>
        /// <param name="root"></param>
        /// <param name="parentNode"></param>
        /// <param name="isLeft"></param>
        /// <param name="key"></param>
        private static void traverseTree(TreeNode root, TreeNode parentNode, bool isLeft, int key)
        {
            if (root == null)
                return;

            var value = root.val;
            if (value == key)
            {
                if (root.left == root.right)
                {
                    if (isLeft)
                        parentNode.left = null;
                    else
                        parentNode.right = null;

                    return;
                }

                //Find left
                if (root.left != null)
                {
                    // find rightmost node, which should not have right child
                    // make its parent node's right child to it's left child
                    var largestNode = root.left;
                    var parent = parentNode; 
                    while (largestNode.right != null)
                    {
                        parent = largestNode;
                        largestNode = largestNode.right;                        
                    }

                    var largestValue = largestNode.val;
                    root.val = largestValue;

                    if (largestNode != root.left)
                    {
                        parent.right = largestNode.left;                       
                    }
                    else 
                    {
                        root.left = largestNode.left;                       
                    }

                    largestNode = null; // set null
                }
                else if (root.right != null)
                {
                    // find leftmost node, which should not have left child
                    // make its parent node's left child to it's right child
                    var smallestNode = root.right;
                    var parent = parentNode;
                    while (smallestNode.left != null)
                    {
                        parent = smallestNode;
                        smallestNode = smallestNode.left;
                    }

                    var smallestValue = smallestNode.val;
                    root.val = smallestValue;

                    if (smallestNode != root.right)
                    {
                        parent.left = smallestNode.right;
                    }
                    else
                    {
                        root.right = smallestNode.right;
                    }

                    smallestNode = null; // set null 
                }

                return;
            }

            if (value < key)
            {
                traverseTree(root.right, root, false, key);
            }
            else
            {
                traverseTree(root.left, root, true, key);
            }
        }
}

227. Basic Calculator II

Here is the link.

It is easy for me to come out the idea using stack to store operator and operands, and it is always to calculate * and / arithmetic calculations first, and then work on + and - operands.
Here are highlights:
  1. Go over the input string once character by character, skip space, push operator into stack, mark * or / operator for immediate processing, parse integer and push into stack as well;
  2. In step 1, if number is pushed into stack, and also high operator is found, then pop three times to calculate the result, push back into stack;
  3. After iteration of input string, go over the stack, process + or - operator, do calculation;
  4. In step 3, I made the mistake on the edge case 1 - 1 + 2, the result should be 2, I calculated 1 - ( 1+ 2) = -2. I did extra checking for operator, if found, then it is popped out, '+' is pushed back in.
public class Solution {
    /// <summary>
        /// Implement the algorithm using data structure - stack 
        /// once *, / sign meet, calculate the value right away; 
        /// once the end of expression, go back to stack and then 
        /// pop one by one to calculate.
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public int Calculate(string s)
        {
            if (s == null || s.Length == 0)
                return 0;

            var length = s.Length;
            var stack = new Stack<string>();
            var digits = "0123456789";
            var operators = "+-*/";
            
            // "3+2*2"
            int index = 0;
            var highOperator = false;

            while (index < length)
            {
                var current = s[index];
               
                if (current == ' ')
                {
                    index++;
                    continue; 
                }

                if (operators.IndexOf(current) != -1)
                {
                    stack.Push(current.ToString());
                    index++;

                    if (current == '*' || current == '/')
                    {
                        highOperator = true; 
                    }
                }

                if(digits.IndexOf(current) != -1)
                {
                    int start = index;
                    int end = index;
                    while(index < length && digits.IndexOf(s[index]) != -1)
                    {
                        end = index;
                        index++;                        
                    }

                    var number = s.Substring(start, end - start + 1);

                    stack.Push(number);
                    if (highOperator)
                    {
                        var number2 = Convert.ToInt32(stack.Pop());
                        var operator1 = stack.Pop();
                        var number1 = Convert.ToInt32(stack.Pop());
                        if(operator1[0] == '*')
                        {
                            stack.Push((number1 * number2).ToString());
                        }
                        else 
                        {
                            stack.Push((number1 / number2).ToString());
                        }

                        highOperator = false;
                    }
                }
            }

            while (stack.Count > 0)
            {
                var unknown = stack.Pop();
                var isOperator = unknown.Length == 1 && operators.IndexOf(unknown[0]) != -1;
                if (!isOperator)
                {
                    var number2 = Convert.ToInt32(unknown);

                    if (stack.Count >= 2)
                    {
                        var operator1 = stack.Pop();
                        var number1 = Convert.ToInt32(stack.Pop());

                        //1-1+2
                        if (stack.Count > 0 && stack.Peek().Length == 1 && stack.Peek()[0] == '-')
                        {
                            stack.Pop();
                            stack.Push("+");
                            number1 *= -1; 
                        }

                        if (operator1[0] == '+')
                        {
                            stack.Push((number1 + number2).ToString());
                        }
                        else if (operator1[0] == '-')
                        {
                            stack.Push((number1 - number2).ToString());
                        }
                    }
                    else
                    {
                        return number2;
                    }
                }
            }      

            return 0; 
        }
}

Case study: January 31, 2019 mock interview and algorithms

May 30, 2019

Introduction


It is time for me to review one of my mock interviews since I found one of Linkedin connections joined Facebook recently. I like to review the mock interview I had with the engineer this January 31, 2019.

Case study




Wednesday, May 29, 2019

Case study: Immigration department letter about permanent resident card photo

May 29, 2019

Introduction

It is my personal finance research. I like to write a case study about my nephew immigration process, this morning I got an email that the photo does not meet permanent resident card requirement. He landed in May 15, and went back to China in May 19. Today is May 29, 2019, I got ...

Top Performing Information Technology ETFs of 2018

Here is the link.


Should I use robo advisor Essential portfolio on Ameritrade.com?

May 29, 2019

Introduction


It is my personal finance research. I like to learn how to hold growth fund and learn how to rebalance every quarter if need. One idea is to open an account and put $5,000 US dollars of my IRA and let Robo advisor to do the work.

Case study


I like to learn how to do rebalance the portfolio and understand the market, my time horizon, and risk tolerance and my finance goal. One of ideas is to open an account on Essential portfolio on Ameritrade.com.


Best ETFs: Sector Funds

Here is the link.

Real estate
SCHHSchwab US REIT ETF*112A4.1
USRTiShares Core US REIT*112B0.5
FRELFidelity MSCI Real Estate161C0.4
VNQVanguard Real Estate194A+30.2
XLREReal Estate Select Sector SPDR213A2.3
RWRSPDR Dow Jones REIT402A2.4
ICFiShares Cohen & Steers REIT532A2.5
KBWYInvesco KBW Premium Yld Eq REIT577B0.4
WREIWilshire US REIT620F0.01
EWREInvesco S&P 500 Eql Wt Rl Estt664D0.02

Technology
FTECFidelity MSCI Information Tech*142A1.9
VGTVanguard Information Technology*147A19.2
XLKTechnology Select Sector SPDR210A+20.4
PSCTInvesco S&P SmallCap Info Tech378C0.4
XSDSPDR S&P Semiconductor384B0.3
IGNiShares North American Tech-Multimedia Networking467C0.1
XWEBSPDR S&P Internet E484F0.01
XNTKSPDR NYSE Technology514B0.9
SMHVanEck Vectors Semiconductor563A+1.4
XSWSPDR S&P Software & Services570D0.1
RYTInvesco S&P 500 Eql Wt Tech647B1.7
XITKSPDR FactSet Innovative Tech651D0.02
XTiShares Exponential Technologies664B2.3
Oil & gas
FENYFidelity MSCI Energy*146B0.6
VDEVanguard Energy151A4.3
XESSPDR S&P Oil & Gas Equipment&Svcs177B0.4
XLEEnergy Select Sector SPDR203A+18.6
XOPSPDR S&P Oil & Gas Explor & Prodtn434A2.8
IEZiShares U.S. Oil Equipment & Services470B0.2
PSCEInvesco S&P SmallCap Energy491D0.1
OIHVanEck Vectors Oil Services567A1.7
RYEInvesco S&P 500 Eql Wt Energy660B0.2
FILLiShares MSCI Global Energy Producers683F0.04
Medical
PBEInvesco Dynamic Biotechnology & Genome-879C0.2
XBISPDR S&P Biotech112A4.7
VHTVanguard Health Care144A7.0
FHLCFidelity MSCI Health Care145B1.1
XPHSPDR S&P Pharmaceuticals174B0.3
XLVHealth Care Select Sector SPDR212A+14.7
IHEiShares U.S. Pharmaceuticals292B0.4
PSCHInvesco S&P SmallCap Health Care397C0.5
XHESPDR S&P Health Care Equipment561C0.3
IBBiShares Nasdaq Biotechnology562A8.9
PPHVanEck Vectors Pharmaceutical569B0.2
BBHVanEck Vectors Biotech575B0.4
XHSSPDR S&P Health Care Services579D0.1
HCRFiShares Edge MSCI Multifactor HlthC610F0.01
RYHInvesco S&P 500 Equal Wt HC649B0.6
Industrials
FIDUFidelity MSCI Industrials*146B0.5
VISVanguard Industrials168B3.5
XLIIndustrial Select Sector SPDR210A+12.1
PSCIInvesco S&P SmallCap Industrials518D0.1
XTNSPDR S&P Transportation544B0.2
XARSPDR S&P Aerospace & Defense544B1.3
ITAiShares U.S. Aerospace & Defense652A5.9

Tuesday, May 28, 2019

Case study: My portfolio

May 28, 2019

Introduction


It is time for me to come out the portfolio of IRA Ameritrade account. I have around $16,000 US dollars right now, I just bought BND ETF two weeks ago, I need to figure out how to set up a portfolio for long term growth.

Case study


I like to work on $12,000 fund and plan to purchase VTI, VYM, VGT, VUG four ETF.
VTI 20 shares x 143
VYM  $84.13 * 40
VUG 
VGT   $197.81 x 20

Case study: Mock interview on lowest common ancestor

May 28, 2019

Introduction


I had a mock interview 10:00 PM today. I asked the interviewee to work on the algorithm called lowest common ancestor, and it turns out that he is super good engineer and very good problem solver.

Case study


The interviewee just showed me how good he was to solve the problem, and also worked on extended problem.

I will add more content here later.

Interviewee feedback


Interviewer feedback


Actionable Items


What I do is to share my learning on Leetcode.com.
C# recursive function to find lowest common ancestor given p and q are in the binary tree (May 28, 2019)
C# recursive function to find lowest common ancestor given p and q (May 28, 2019)

Best Canadian ETFs for 2019

Here is the link.

Best Canadian ETFs – The list


ETF nameTickerManagement FeeMER# of HoldingsDescription
Vanguard FTSE Canada All Cap Index ETFVCN0.050.06212Exposure to Canadian small, medium and large caps, ultra low fee
iShares Core S&P/TSX Capped Composite Index ETFXIC0.050.06250Tracks Canada's best known index with a very low fee
Horizons S&P/TSX 60 ETFHXT0.030.0360Tax-efficient
BMO S&P TSX Capped Composite IDX ETFZCN0.050.06251Fee as low as VCN and XIC; more assets than VCN