Saturday, June 22, 2019

210 course schedule II

Here is my discussion post.

It is challenge for me to master a graph algorithm. I plan to spend time to review my practice back in February, 2017 first. I like to share my practice and will work on new version very soon.
Case study example graph
Example 2:
Input: 4, [[1,0],[2,0],[3,1],[3,2]]
Output: [0,1,2,3] or [0,2,1,3]
In order to understand graph, how to apply topological sort, we have to understand the dependency stored in the array, [1,0] tells us that course 0 should be taken first then course 1 can be taken. likewise, we can interpret [2,0],[3,1],[3,2].
Let me draw the tree based on the above dependency, the graph can be very helpful to understand how to approach the problem using topological sorting; even if I forget the algorithm, I still can figure out the reasonable order based on those prerequisite courses.
image
The most challenge part is design decision. How to represent the graph using data structures? We can name the node using index = 0, 1, ...n, and each node ( course) has dependents; so the course can be prerequisite course for others, it can be stored in a stack, and then each course has indgree ( the concept is prerequisite courses) value.
So declaration statements are the following:
var dependents = new Stack[numCourses];
var indegree = new int[numCourses];
The output of courses taken in order is stored in integer array.
Build the graph by going over each entry in matrix.
Next step is to add those courses into queue with 0 indegree. Take those course first, and then update indegree for each course if related.
Here are highlights:
  1. Build a graph using selected data structures, indegree, dependency list;
  2. Start to do BFS search using Queue, add those indegree courses to the queue;
  3. Do not forget to update indegree count after the course is ready to take based on indegree value 0;
  4. Work on example graph if there is problem in thinking process. Be patient! Example graph, take course 0, next step take 1 or 2, and then take one from 1 or 2 if it is not taken before, and last step take course 3.
public class Solution {
    public int[] FindOrder(int numCourses, int[,] prerequisites) {
         var dependents = new Stack<int>[numCourses];

            for (int i = 0; i < numCourses; ++i)
            {
                dependents[i] = new Stack<int>();  
            }

            // build dependency list for each prerequisite course, 
            // and set up indegree variable for each courses matching with prerequisite courses' number.
            int[] indegree = new int[numCourses];
            for (int i = 0; i < prerequisites.GetLength(0); ++i)
            {
                int takeFirst = prerequisites[i, 1];
                int takeAfter = prerequisites[i, 0];

                dependents[takeFirst].Push(takeAfter); 
                ++indegree[takeAfter];             
            }

            // add those courses with 0 indegree to the queue
            Queue<int> queue = new Queue<int>();
            for (int courseId = 0; courseId < numCourses; ++courseId)
            {
                if (indegree[courseId] == 0)
                {
                    queue.Enqueue(courseId);
                }
            }

            // take courses with indgree zero only
            var coursesByTakingOrder = new int[numCourses];
            int count = 0;
            while (queue.Count > 0)
            {                   
                int readyToTake = queue.Dequeue();

                coursesByTakingOrder[count++] = readyToTake;   

                foreach (int courseId in dependents[readyToTake])
                {
                    // decrement value of indegree by 1 
                    indegree[courseId]--;

                    // add to the queue if there is no prerequisite left
                    if (indegree[courseId] == 0)   
                    {
                        queue.Enqueue(courseId);
                    }
                }
            }

            if (count != numCourses)
            {   
                return new int[]{}; 
            }

            return coursesByTakingOrder;
    }
}


133. Clone Graph - my practice in July 2018

June 22, 2019

Introduction


It is my personal opinion. I was afraid to write down the thinking process when I practiced last time back in July 2018. I understand that it is important to show how I approach a problem, why it is better to choose BFS instead of DFS, what is challenge problem to solve to clone a node.

My sharing


Here is my post to share written on June 22, 2019.

It is challenge to master a graph algorithm. I like to review my last practice back in July 2018; I think that I should spend some time to work on a case study on example graph, and then explain how it works based on breadth first search.
Here are highlights:
  1. Apply breadth first search in original graph;
  2. Build a hashmap to map any node in original graph and clone graph;
  3. To visit any neighbor node, if it is the first time to visit, then the node should be added to hashmap first, and also it should be added to queue to visit its neighbors in next level of BFS; otherwise update clone graph node and its neighbor node connection.
Case study example graph
June 22, 2019
I think that it is important for me to work on an example, and then write down every step if I have time, and then I can review the basics how to clone a node with neighbors using BFS.
The nodes 1 has two neighbors, node 2 and 4.
I like to explain how to clone the graph with node 1 with two neighbor nodes 2 and 4.
First visit node 1, and then create a new node for clone graph, assign value of node 1; And also add entry in hashmap to make node 1 and clone of node 1.
Go over all neighbors of node 1, node 2 and node 4; first visit node 2, and see if
hashmap has an entry for node 2 or not.
If there is no entry in hashmap for node 2, so create a new node in clone graph, copy the value of node 2, and then add map from node 2 to clone node of node 2; and also add clone neighbor relationship, and last, it is most important to visit neighbor by adding neighbor node to the queue.
The hashmap is also to serve visited look up, if the node is visited, then it should have an entry in hashmap.
If the neighbor node is visited, all we need to do is to add one more neighbor relationship.
Do not forget, search all nodes in the graph; always mark visit, avoid deadloop; Do not forget to clone neighbor relationship in clone graph as well.
The best way to review the graph algorithm is to draw a diagram to illustrate the steps in the clone process. I did quickly draw a diagram, which will be enhanced later.
image
/**
 * Definition for undirected graph.
 * public class UndirectedGraphNode {
 *     public int label;
 *     public IList<UndirectedGraphNode> neighbors;
 *     public UndirectedGraphNode(int x) { label = x; neighbors = new List<UndirectedGraphNode>(); }
 * };
 */
public class Solution {
    public UndirectedGraphNode CloneGraph(UndirectedGraphNode node)
        {
            if (node == null)
            {
                return null;
            }

            var queue = new Queue<UndirectedGraphNode>();
            var map   = new Dictionary<UndirectedGraphNode, UndirectedGraphNode>();

            var newHead = new UndirectedGraphNode(node.label);

            queue.Enqueue(node);
            map.Add(node, newHead);

            while (queue.Count > 0)
            {
                var curr = (UndirectedGraphNode)queue.Dequeue();

                var currNeighbors = curr.neighbors;

                foreach (UndirectedGraphNode neighbor in currNeighbors)
                {
                    if (!map.ContainsKey(neighbor))
                    {
                        var copy = new UndirectedGraphNode(neighbor.label);

                        map.Add(neighbor, copy);

                        map[curr].neighbors.Add(copy);

                        queue.Enqueue(neighbor);
                    }
                    else
                    {
                        map[curr].neighbors.Add(map[neighbor]);
                    }
                }
            }

            return newHead;
        }
}

133. Clone Graph - My first practice back in July 2016

Here is the discussion post I wrote today.

It is challenge to master the graph algorithm. What I do is to review all graph algorithms, and then review basics through my past practice.
Here are highlights of my practice back in July 2016.
  1. Clone a graph is similar to clone a tree; The traverse of a graph can be depth first search or breadth first search, each node should be copied, and then connected node should be keeped in clone graph as well;
  2. Design a hashmap to save the orginal node in graph with cloned graph; Start from any given node first;
  3. Choose breadth first search, since adjacent list should be went through and then each neighbor node should be cloned as well.
June 22, 2019
I think that I should work on a few things back in 2016. I should write some comment, and also I should learn some advanced C# feature, like using implicit type var to declare queue to save time.
/**
 * Definition for undirected graph.
 * public class UndirectedGraphNode {
 *     public int label;
 *     public IList<UndirectedGraphNode> neighbors;
 *     public UndirectedGraphNode(int x) { label = x; neighbors = new List<UndirectedGraphNode>(); }
 * };
 */
public class Solution {
    public UndirectedGraphNode CloneGraph(UndirectedGraphNode node) {
        if(node == null)
                return null;
 
            Queue<UndirectedGraphNode> queue = new Queue<UndirectedGraphNode>();
            Dictionary<UndirectedGraphNode, UndirectedGraphNode> map = 
                                   new Dictionary<UndirectedGraphNode,UndirectedGraphNode>();
 
            UndirectedGraphNode newHead = new UndirectedGraphNode(node.label);
 
            queue.Enqueue(node);
            map.Add(node, newHead);
 
            while(queue.Count > 0 ){
                UndirectedGraphNode curr = (UndirectedGraphNode)queue.Dequeue();                

                IList<UndirectedGraphNode> currNeighbors = curr.neighbors; 
 
                foreach (UndirectedGraphNode aNeighbor in currNeighbors){
                    if(!map.ContainsKey(aNeighbor)){
                        UndirectedGraphNode copy = new UndirectedGraphNode(aNeighbor.label);

                        map.Add(aNeighbor,copy);

                        map[curr].neighbors.Add(copy);

                        queue.Enqueue(aNeighbor);
                    }else{
                        map[curr].neighbors.Add(map[aNeighbor]);
                    }
                } 
            }

            return newHead;
    }
}


Graph problems

June 22, 2019

Introduction


It is time for me to go over some graph problems before I plan to take online code assessment. I need to learn how to master the graph problem, and also most important is to learn to write a simple graph solution using 90 minutes time range.

How to prepare 90 minutes online assessment for a graph problem?


It is better for me to read the second algorithm in the first 10 minutes, so I can prepare early for the second algorithm.

Next I should push myself to solve the first algorithm as quick as possible; Also I need to prepare for the second algorithm.

I like to go over 10 graph problems to warm up. Here are the graph problems on leetcode.com.


The Risk of Playing It Too Safe

Here is the link. My favorite personal finance director Christian Benz and her interview.

The risk you buy high and sell low.


Benz: So how do you coach clients, then, in a terrible market environment like '08 and early, '09 when everyone's wanting to move to cash, do you give into that tendency or how do you fight against that at a time like that?
Balasa: It's a varied answer to your question. Our clients looking back at that timeframe, if you let them go to 5% or 10% cash, it didn't make a big difference to the total return in the portfolio frankly, but psychologically, it was a huge release. They felt like they did something to preserve principal.
Benz: So saying stay put, we're not going to change anything doesn't cut it?
Balasa: After about five or six months of seeing staying put as the market is going down, they get really old. And so this was kind of an emotional release. But for most people, if you can step back and if you run projections, again, coming back to the idea of looking at numbers for yourself, if you see that I have a 150% of what I need and now the market is going down, I have a 110% of what I need. It gives you the ability to stay.
Now, if you've got 80% of what you need, and I have 60%, but then maybe you have to make some different decisions. But again, coming back and looking at the big picture is really helpful to keep that nervous investor in the market.


回答关于我的100个问题!

Here is the link.


10 things people learn too late

1. Everything is temporary
2. Life isn't fair
3. Family matters more than friends
4. Others treat you the way you treat yourself
5. Beneath anger there's always fear
6. Happiness is a choice and requires hard work
7. A lifetime isn't so long as you think
8. The biggest risk is not taking any risk
9. Things don't matter so much
10. You played it too safe

Warren Buffet

ryanscribenerofficial

90. Subsets II

Here is C# practice using recursive solution, I studied the code written by an Amazon engineer. 

It is important for me to learn how to write a simple recursive solution. Since my iterative solution takes me more than one hour to complete the code and testing.
I like to learn how to write a simple recursive solution, so I can solve it in less than 15 minutes. One thing I can do is to study code, and then write down how I understand the code.
public class Solution {
    /// <summary>
        /// June 22, 2019
        /// study code
        /// https://leetcode.com/problems/subsets-ii/discuss/30214/C-recursive
        /// The importance to learn to write a recursive function.
        /// I need to finish the code in less than 15 minutes. 
        /// I need to shorten the time to write a solution, recursive function is the first choice. 
        /// </summary>
        /// <param name="numbers"></param>
        /// <returns></returns>
        public  IList<IList<int>> SubsetsWithDup(int[] numbers)
        {
            // sets - good name? 
            var sets = new List<IList<int>>();

            Array.Sort(numbers);

            buildSubsets(numbers, sets, 0, new List<int>());

            return sets;
        }

        /// <summary>
        /// I need to learn how to write a recursive solution. 
        /// </summary>
        /// <param name="numbers"></param>
        /// <param name="sets"></param>
        /// <param name="index"></param>
        /// <param name="currentSet"></param>
        private void buildSubsets(int[] numbers, IList<IList<int>> sets, int index, List<int> currentSet)
        {
            sets.Add(currentSet);

            for (int i = index; i < numbers.Length; i++)
            {
                var current = numbers[i];

                var nextSet = new List<int>(currentSet); // copy the list

                nextSet.Add(current);

                buildSubsets(numbers, sets, i + 1, nextSet);

                // input list is sorted
                while (i < numbers.Length - 1 && numbers[i] == numbers[i + 1])
                {
                    i++;
                }
            }
        }
}

Top 10 Financial Habits of Warren Buffett

June 22, 2019

Introduction


It is my personal finance research. I like to learn more about 10 financial habits of Warren Buffett. Here is the article.

Habit #1: Stay Out of Debt and Save

  • Live below your income.
  • Save your money.
  • Avoid debt. Stay away from credit cards.

Habit #2: Read, Study, Learn

  • Read everything you can.
  • Understand business and accounting.
  • Learn everything you can about investing and potential investments before you invest.
  • Think through the investment process.
  • Research businesses and their histories.
  • Learn how to determine intrinsic value.
  • Set goals for yourself.
  • Emulate the best in every field of endeavor.
  • Learn from your mistakes.

Habit #3: Buy Businesses

Wealth is created and preserved through owning businesses. Begin investing early in life. Buying a business usually means buying shares of stock in a company. As a stockholder, you own a portion of the business. You should use the same criteria for deciding to buy a stock as you would use for deciding to buy the entire company. Before you buy shares in a company, consider whether you would buy the entire business. Invest in companies that you really like and that earn money. Use those earnings to buy more businesses.

Habit #4: Understand What You Own

Know and understand the businesses in which you own shares. Study and analyze what is going on inside the business, not what is going on in the outside markets. The business should be simple. Never invest in a business you cannot understand. You should be able to explain to an 8-year-old child in one or two sentences how the company makes a profit. You should know enough about an investment to be able to calculate its value.

Habit #5: Invest in Value

You should determine a business’ intrinsic value and buy it at a fair or bargain price. Look for companies with:
  • Above-average returns on equity, regardless of earnings per share
  • Sustainable earnings
  • Consistent operational history
  • Good four- or five-year averages, rather than just yearly results
  • High profit margins
  • Consumer products and brand names that enable the companies to raise their prices above the rate of inflation
  • Products such as food that are recession- and depression-proof
  • Barriers to outside competition
  • Good long-term prospects
  • Opportunities for future growth
  • Competent and honest management

Habit #6: Choose Well-Managed Businesses

Choose businesses that have rational and competent management. The management should be open and honest with shareholders. The management should resist the “institutional imperative,” which is the tendency to imitate other corporate managements, even when their behavior is irrational or dishonest. Nevertheless, the intrinsic quality of a business is more important than its management.

Habit #7: Invest for the Long Term

Maintain a focused, low-turnover portfolio. Always make the decision to buy a stock based on owning it for the long term. The best investments are companies that have low-capital requirements and products that people will always want to buy. Resist the urge to buy and sell investments. Inactivity is usually preferable to action. Invest for the long term, rather than constantly investing in broadly diverse prospects for the short term.

Habit #8: Maintain a Margin of Safety

Investment risk comes from being an unprepared, uninformed investor. Ensure a margin of safety with each of your investments. Your margin of safety comes from getting more intrinsic value than you are paying for when investing. Moreover, your margins of safety insulate you from mistakes in judgment and business cycles and unforeseen events. Investment risk can be also be greatly reduced by concentrating on only a few holdings.

Habit #9: Ignore the Stock Market

  • Judge a business by its fundamentals, not by short-term changes in its stock price.
  • Understand the difference between investments and speculation.
  • Avoid the speculative and emotional market forces.
  • Do not try to predict the direction of the stock market, interest rates, the economy or elections.
  • If you cannot watch your stock portfolio decline by 50% without panicking, you should not be investing in the stock market.

Habit #10: Give Back to Society

When you can afford it, donate some of your wealth to worthy causes and for the betterment of society. You can always contribute your time and effort to deserving charitable foundations and organizations. Mr. Buffet has donated around 85% of his wealth (over $37 billion in 2006) to help solve some of the major problems in the world.


90. Subsets II

Here is the post.

C# counting sort and then work on same integer together

It is my first practice in 2019. I choose to sort the number in the array and then save into SortedDictionary using counting sort, and then work on each integer in ascending order one by one.
Case study [1, 2, 2]
Counting sort, so there is one for number 1, two for number 2.
Work on each integer in ascending order one by one. First one is empty set, and then work on number 1, each set is appended by number 1, and then next number 2, we work together those two numbers with the same value 2.
The are three cases for two numbers with the same value 2. 0 copy, 1 copy, or two copies, three options.
So the answer will be
[]
[1],
[] appended by 2 zero time, 1 time, two times, [], [2], [2,2]
[1] appended by 2 zero time, 1 time, two times, [1],[1,2], [1, 2,2]
The way we handle the numbers in the above, the duplicate numbers will not be created.
Here are highlights:
public class Solution {
    /// <summary>
        /// June 22, 2019
        /// The idea is to sort the numbers using counting sort and 
        /// save it in SorteDictionary<int, int>.
        /// </summary>
        /// <param name="nums"></param>
        /// <returns></returns>
        public IList<IList<int>> SubsetsWithDup(int[] numbers)
        {
            if (numbers == null || numbers.Length == 0)
                return null;

            var sorted = new SortedDictionary<int, int>();

            var length = numbers.Length;
            for(int i = 0; i < length; i++)
            {
                var current = numbers[i];
                if (!sorted.ContainsKey(current))
                    sorted.Add(current, 0);

                sorted[current]++;
            }

            var result = new List<IList<int>>(); 
            // empty set - base case
            var sublist = new List<int>();
            var list = new List<IList<int>>();
            //list.Add(sublist);  // caught by debugger

            foreach(var key in sorted.Keys)
            {
                var value = sorted[key];
                var nextList = new List<IList<int>>();

                // edge case
                if (list.Count == 0)
                {
                    var nextSubList1 = new List<int>();
                    nextList.Add(nextSubList1);

                    for (int i = 0; i < value; i++)
                    {
                        var nextSubList = new List<int>();
                        for (int j = 0; j <= i; j++)
                        {
                            nextSubList.Add(key);
                        }

                        nextList.Add(nextSubList);
                    }
                }
                else
                {
                    foreach (var subList in list)
                    {
                        var nextSubList1 = new List<int>(subList);
                        nextList.Add(nextSubList1);

                        for (int i = 0; i < value; i++)
                        {
                            var nextSubList = new List<int>(subList);
                            for (int j = 0; j <= i; j++)
                            {
                                nextSubList.Add(key);
                            }

                            nextList.Add(nextSubList);
                        }
                    }
                }

                // move to next unique number
                list = new List<IList<int>>();
                foreach (var subList in nextList)
                {
                    var copySubList = new List<int>(subList);
                    list.Add(copySubList);
                }
            }

            return list; 
        }
}


How often should you review your asset of allocation?

June 22, 2019

Introduction


It is time for me to learn how to review my asset of allocation. It is hard for me to start, I just started back in May 2019.


Sequence Risk

Here is the link.


51. N-Queens

Here is my post written on June 22, 2019. The code was submitted on January 26, 2016. I missed 2016. I got my first onsite in the city of Vancouver, Canada.




39. Combination Sum

C# DFS practice in 2017, here is the link.

Women's final #RG19

Here is the link.


Christine Benz: Managing Volatility

Here is the link.

Do not peek.

I like to learn something called "Do not peek." Should I get my $1000 dollars gain, and then rebuilt my portfolio when the market crashes? I learn the importance to stay in the market, do not time the market.

Facts to review

I just built a portfolio in less than one month, then I have 4.8% return on VOO ETF, and then dividend from VEU $65.00 dollars.

I need to learn how to review my allocation, and then also learn how to monitor my portfolio.

Jeff Logo - Do not peek. Long time investor do not peek. More incline to trade.