Friday, August 23, 2019

33. Search in Rotated Sorted Array

Here is the link.

I had practice on binary search algorithm Rotated sorted array on pramp.com more than 10 times back in 2017. But I still could not clear the interview on 2019 August on this algorithm. I wrote the code with bugs, and then I did not pay attention to possible bugs like TLE, index-out-range, wrong answer.
What I like to do is to work on various ideas as possible this time, remove bias; Give every idea a chance to live, try to code it and make it work.
Time Line: 2019 August 20
Onsite interview, whiteboard version with bugs on August 20, 2019, California, MPK, here is the link.
Time Line: 2019 August 22
Optimal solution, avoid middle - 1 or middle + 1, practice on August 22, 2019. Here is the link.
Time Line: 2019 August 23
Work on idea to define left half [start, middle - 1], practice on August 23, 2019. here is the link.
Time Line: 2017
My practice in 2017. Here is the link.
Time Line: 2017
Common mistakes in binary search is my favorite research topic in 2017. Here is the blog.
My mock interview practice in 2017, here is the blog with source code link in the blog as well.
pramp.com 10 rounds of mock interview
https://github.com/jianminchen/Mock-interviews
Algorithm is called shifted array search, here is the folder to contain all practice for mock interviews.
2017 07 1st round June - July, here is the link.
2017 2nd round July - Sept, here is the link.
2017 3rd round Nov - Dec, here is the link.
2018 Jan - Feb, here is the link.
2018 Feb 7 - Feb 25, here is the link.
2018 March 30 - May 4, here is the link.
2018 June 16, here is the link.


33. Search in Rotated Sorted Array

Here is the link.

C# Case study: Road to executable code on August 20, 2019

I went to onsite and then I had a coding interview to write code on white board. The stardard is high, one of advice is to write executable code. What I did is to try to write the code using the idea shared my post written on August 22, 2019, here is the link.
I like to share my code written on white board, and then discuss bugs I created, compared to executable code, how many things I can think about working on, make improvements.
My code written has index-out-of-range error since middle - 1 and middle + 1 is out-of-range.
Given the rotated sorted array [3, 1], target is 1, the code will not work at all.
 /// modified binary search 
        public int Search(int[] numbers, int target)
        {
            if (numbers == null || numbers.Length == 0)
                return -1;

            var start = 0;
            var end = numbers.Length - 1;

            while (start <= end)
            {
                var middle = start + (end - start) / 2;
                var middleValue = numbers[middle];

                if (middleValue == target)
                    return middle;
                
                // two range [start, middle - 1], [middle + 1, end]
                // range can be one value only           
                var leftAsc  = numbers[middle - 1] >= numbers[start]; // bug: out-of-range error
                var rightAsc = numbers[end] >= numbers[middle + 1];

                // missing cases
                if (leftAsc && isInRange(target, new int[] { numbers[start], numbers[middle - 1] }))
                {                    
                    end = middle - 1;                    
                }
                else if (rightAsc && isInRange(target, new int[] { numbers[middle + 1], numbers[end] }))
                {
                    start = middle + 1; 
                }
            }

            return -1;
        }

        private static bool isInRange(int target, int[] range)
        {
            return target >= range[0] && target <= range[1];
        }
Follow up on August 23, 2019
Give every idea a chance to live
I spent extra 20 minutes to make the above idea work, still check range [start, middle - 1]. Here is the link.
C# various practices in 2019, here is the link.


33. Search in Rotated Sorted Array

C# modified binary search practice on August 22, 2019

Here is the link. 

It is most challenging solution to write. The idea is based on the argument that there is only at most one pivot value in the array ( the pivot value is bigger than left one and right one), at least one range is in ascending order. I should use the ascending range to determine which half should be get rid of. Do not say that only in important onsite interview, use an example to explain the idea as well.
Case study 1
I believe that it is important to do a case study, explain the idea using the test case. So interviewer and interviewee can both understand the algorithm. It is important to explain using concrete test case, go through the test case to explain how to find the solution.
Given a rotated sorted array [4, 5, 6, 7, 0, 1, 2}, target = 0.
start = 0, end = 6,
middle = start + (end - start)/ 2 = 3, so binary search should divide range into two using index = 3.
We like to look into two ranges, first one is Range 1: [4, 5, 6, 7], and then second one is Range 2: [7, 0, 1, 2]
We know that at least one of ranges is in ascending order, since at most one pivot value in the array.
For example, [4, 5, 6, 7, 0, 1, 2], the pivot value is 7, index = 3, which is bigger than left one, 6; also bigger than right one 0.
Range 2: [7, 0, 1, 2] is not in ascending order, but Range 1: [4, 5, 6, 7] is. I can use the Range 1 to get rid of half numbers in search, since 0 is not in range, so Range 1 can be removed in search.
Case study 2
I like to write a case study on [3, 1], target = 1.
So first search, start = 0, end = 1;
middle = 0;
middle index position divides the array into two ranges.
First one is [start, middle], [0,0], only one node in the range.
Second one is [middle, end], [0, 1], two nodes in the range.
We always take one node range is ascending.
So numbers[0] = 3, comparing to target 1, which is not in the range.
Binary search will move to range [1,1].
apply middle calculation again, middle = 1;
Two ranges, one is [1,1], second one is [1,1].
numbers[1] == target, find the value.
Common mistakes
Common mistakes of binary search is my favorite research topic. I like to figure out how to find more to list in the following:
  1. Index-out-range error
  2. One number in search range, range not existing
  3. Time limit exceeded
  4. Missing cases in analysis
Advice:
  1. Always work on middle and value on middle index;
  2. Be careful about index-out-range error, do not assume that middle -1 or middle + 1 is in range of numbers array;
  3. Double check basic logic checking;
  4. The algorithm is the best algorithm for onsite or mock interview; Since it is easy to write code with index-out-of-range, timeout bug etc.
  5. Work hard on common mistakes in binary search. I wrote one blog on this topic back in 2017. I should continue to work on this topic.
Drills
To train myself to write executable code in 20 minutes interview, I like to come out some drills for me to practice.
  1. Test case [3, 1], target 1, see if return value 1 instead of -1;
  2. More will be added here later.
public class Solution {
    /// modified binary search 
    public int Search(int[] numbers, int target) {
        if(numbers == null ||  numbers.Length == 0)
            return -1; 
        
        var start = 0; 
        var end   = numbers.Length - 1; 
        
        while(start <= end)
        {
            var middle = start + (end - start)/ 2; 
            var middleValue = numbers[middle];
            
            if(middleValue == target)
                return middle;                                             
   
   // Do not consider middle - 1 or middle + 1, which may be out of range of numbers array
            // two range [start, middle], [middle, end]
            // range can be one value only           
            var leftAsc    = middleValue   >= numbers[start] ;
            var rightAsc = numbers[end] >= middleValue; 
            
            if(leftAsc)
            {
               if (isInRange(target, new int[]{numbers[start], middleValue}))
               {
                   end = middle - 1; 
               }
               else 
               {
                   start = middle + 1; 
               }
            }
            else if(rightAsc)
            {
                if (isInRange(target, new int[]{middleValue, numbers[end]}))
               {
                   start = middle + 1; 
               }
               else 
               {
                   end = middle - 1; 
               }
            }           
        }
               
        return -1;         
    }
               
    private static bool isInRange(int target, int[] range)
    {
        return target >= range[0] && target <= range[1];
    }
}
C# various practices in 2019, here is the link.

33. Search in Rotated Sorted Array

I wrote a post and shared my practice.

C# introduce middle -1 and middle + 1 practice in August 23, 2019

Here is the link.

I am searching good ideas to practice. What I think is to write excecutable code for all kinds of ideas, and make it work first; Do not have bias on ideas, do not memorize the solution.
It is fine not coming out optimal solution. The following solution is hard to write compared to the one I wrote in August 22, 2019, avoid middle + 1 or middle -1. Here is the link.
Case study - given array [3, 1], target = 1
I like to write a case study on [3, 1], target = 1.
So first search, start = 0, end = 1;
middle = 0;
middle index position divides the array into two ranges.
First one is [start, middle - 1], [0,-1], the range is not existing.
Second one is [middle + 1, end], [1, 1], one node is in the range.
First one is not existing. So second one is in ascending order.
So numbers[1] = 1, comparing to target 1, the target is found.
Case study - given array [4, 5, 6, 7, 0, 1, 2], target = 3
I like to write a case study on [4, 5, 6, 7, 0, 1, 2], target = 3.
So first search, start = 0, end = 6;
middle = start + (end - start)/ 2 = 3;
middle index position divides the array into two ranges.
First one is [start, middle - 1], or [0,2], numbers in the range are {4, 5, 6}.
Second one is [middle + 1, end], or [4, 6], numbers in the range are {0, 1, 2}.
First one is in ascending order, target value 3 is not in the range [4,6]. So next search area is start = 4, end = 6, or the array {0, 1, 2}.
middle = start + (end - start)/2 = 5.
two ranges to consider, left one is [4, 4], or array {0}, it is in ascending order, target is not in. So next search area is [6,6], or array {2}.
I like to write some case studies since I learn that algorithm practice without getting hands dirty on concrete example is too risky. I should carefully consider what to choose, how to design, but my goal is to make any idea I thought about reality. Therefore, I can challenge myself to build strength as a problem solver.
Case study - given array [2], target = 3
The reason I like to do a case study is that I came cross TLE error. The base case should include the case, array with one number, but not target value.
What I like to do is to go over my design of diving into two halves, why it is not working for this case.
Array: [2], target = 3
start = 0, end = 0.
middle = start + (end - start)/2 = 0.
so left half [start, middle - 1], or [0, -1], not existed at all.
right half [middle + 1, end], or [1, 0], not existed at all.
Combining the above two cases, there is no work done to handle this case. That is the reason a new base should be added to handle it instead.
// Avoid time limit exceeded bug
if (start == end)
return -1;
Things get complicated?
Because I like to introduce middle - 1 and middle + 1 in binary search, I create extra tasks for me to handle. I also should go over a check list based on common mistakes to help me make the idea work perfectly. Just be patient, and work on a simple test case like given an array [2], target = 3.
Here are highlights:
  1. Use depth first search, middle is base case; one iteration at least one value will be get rid of, so there is no deadlock.
  2. Use middle position to divide into two ranges, [start, middle - 1], [middle + 1, end], the left range or right range may not exist at all, since middle - 1 < start may be true.
  3. Add constraint check in case of index-out-range error, (middle - 1) >= start for leftAsc;
  4. Add constraint check in case of index-out-range error, (middle + 1 <= end) for rightAsc
  5. I ran into Leetcode online judge TLE error, test case [4, 5, 6, 7, 0, 1, 2], target 3, so I added two more lines of code to avoid TLE; If the range is 1, return -1. The first of 193 cases is failed.
    if(start == end)
   return -1;
The following code passes online judge.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _33_Rotated_sorted_Array___Catchup
{
    class Program
    {
        static void Main(string[] args)
        {
            RunTestcase(); 
        }

        /// <summary>
        ///  TLE - time limit exceeded 
        /// </summary>
        public static void RunTestcase()
        {
            var result = Search(new int[] {4, 5, 6, 7, 0, 1, 2}, 3);
        }

        /// modified binary search 
        public static int Search(int[] numbers, int target)
        {
            if (numbers == null || numbers.Length == 0)
                return -1;

            var start = 0;
            var end = numbers.Length - 1;

            while (start <= end)
            {
                var middle = start + (end - start) / 2;
                var middleValue = numbers[middle];

                if (middleValue == target)
                    return middle;

                // Avoid time limit exceeded bug
                if (start == end)
                    return -1; 

                // two range [start, middle - 1], [middle + 1, end]
                // range can be one value only   
                // Range definition should be added
                var leftAsc  = (middle - 1) >= start && numbers[middle - 1] >= numbers[start]; 
                var rightAsc = (middle + 1 <= end) && numbers[end] >= numbers[middle + 1];

                // missing cases
                if (leftAsc)
                {
                    if (isInRange(target, new int[] { numbers[start], numbers[middle - 1] }))
                    {
                        end = middle - 1;
                    }
                    else
                    {
                        start = middle + 1; 
                    }
                }
                else if (rightAsc)
                {
                    if (isInRange(target, new int[] { numbers[middle + 1], numbers[end] }))
                    {
                        start = middle + 1;
                    }
                    else
                    {
                        end = middle - 1; 
                    }
                }
            }

            return -1;
        }

        private static bool isInRange(int target, int[] range)
        {
            return target >= range[0] && target <= range[1];
        }
    }
}
C# various practices in 2019, here is the link.


Thursday, August 22, 2019

33. Search in Rotated Sorted Array

August 22, 2019

Introduction


It is always a good idea to review my submission through Leetcode.com. I like to figure out how to improve myself in order to be a better problem solver. One thing I can tell is to share my submission, and talk about it.

2017 practice


Here is my post. I wrote a post and shared it after 2 years.

Actionable Items


I like to figure out how to be a better person in terms of listening, and following advice from others. It is hard for me to discipline myself. Sometimes I can be very rude, because I have some bad habit and it is hard for me to correct them in important onsite interviews.

I did spend over one hour to write the code back in 2017.




Case study: Rotated Sorted array

August 22, 2019

Introduction


I like to write a case study how the interviewee performed on this algorithm in my mock interview. As an interviewer, I observed how she worked hard and solved the algorithm. It took her 40 minutes.

Case study


Here is the C++ code for me to do code review. The interviewee tried a few test cases and then she figured out how to write correct solution. It took her more than 25 minutes,  but definitely she was on the track.

33. Search in Rotated Sorted Array

August 22, 2019

Introduction


It is my favorite binary search algorithm. I practiced so many times on binary search algorithm, and today I like to practice one more solution, and start to work on show case how to solve a binary search algorithm quickly and also bug-free. I overestimated myself and wrote a few bugs recently on one of onsite interview, and I did not listen to fix the bug to try more test cases.


One more practice 


Here are the blogs I wrote related to Search in rotated sorted array in 2017.

Here is the post I wrote today.

C# modified binary search practice on August 22, 2019

It is most challenging solution to write. The idea is based on the argument that there is only at most one pivot value in the array ( the pivot value is bigger than left one and right one), at least one range is in ascending order. I should use the ascending range to determine which half should be get rid of. Do not say that only in important onsite interview, use an example to explain the idea as well.
Case study
I believe that it is important to do a case study, explain the idea using the test case. So interviewer and interviewee can both understand the algorithm. It is important to explain using concrete test case, go through the test case to explain how to find the solution.
Given a rotated sorted array [4, 5, 6, 7, 0, 1, 2}, target = 0.
start = 0, end = 6,
middle = start + (end - start)/ 2 = 3
We like to look into two ranges, first one is Range 1: [4, 5, 6, 7], and then second one is Range 2: [7, 0, 1, 2]
We know that at least one of ranges is in ascending order, since at most one pivot value in the array.
For example, [4, 5, 6, 7, 0, 1, 2], the pivot value is 7, index = 3, which is bigger than left one, 6; also bigger than right one 0.
Range 2: [7, 0, 1, 2] is not in ascending order, but Range 1: [4, 5, 6, 7] is. I can use the Range 1 to get rid of half numbers in search, since 0 is not in range, so Range 1 can be removed in search.
Common mistakes
Common mistakes of binary search is my favorite research topic. I like to figure out how to find more to list in the following:
  1. Index-out-range error
  2. One number in search range
  3. Missing cases in analysis
Advice:
  1. Always work on middle and value on middle index;
  2. Be careful about index-out-range error, do not assume that middle -1 or middle + 1 is in range of numbers array;
  3. Double check basic logic checking;
  4. The algorithm is the best algorithm for onsite or mock interview; Since it is easy to write code with index-out-of-range, timeout bug etc.
  5. Work hard on common mistakes in binary search. I wrote one blog on this topic in 2017.
public class Solution {
    /// modified binary search 
    public int Search(int[] numbers, int target) {
        if(numbers == null ||  numbers.Length == 0)
            return -1; 
        
        var start = 0; 
        var end   = numbers.Length - 1; 
        
        while(start <= end)
        {
            var middle = start + (end - start)/ 2; 
            var middleValue = numbers[middle];
            
            if(middleValue == target)
                return middle;                                             
   
   // Do not consider middle - 1 or middle + 1, which may be out of range of numbers array
            // two range [start, middle], [middle, end]
            // range can be one value only           
            var leftAsc    = middleValue   >= numbers[start] ;
            var rightAsc = numbers[end] >= middleValue; 
            
            if(leftAsc)
            {
               if (isInRange(target, new int[]{numbers[start], middleValue}))
               {
                   end = middle - 1; 
               }
               else 
               {
                   start = middle + 1; 
               }
            }
            else if(rightAsc)
            {
                if (isInRange(target, new int[]{middleValue, numbers[end]}))
               {
                   start = middle + 1; 
               }
               else 
               {
                   end = middle - 1; 
               }
            }           
        }
               
        return -1;         
    }
               
    private static bool isInRange(int target, int[] range)
    {
        return target >= range[0] && target <= range[1];
    }
}

Wednesday, August 21, 2019

Monday, August 19, 2019

Go to Facebook campus on 8:00 AM

I plan to go to Facebook campus 8:00 AM on August 20, 2019.


Go out to visit Stanford campus

August 19, 2019

It is the challenge job to be a good manager. I like to take some time off today and visit Stanford campus.

What can compare to Stanford campus visit?

I am over 50 years old. But I think that it is like in my 20s. I visited Stanford campus back in 1999. Twenty years ago.

I like to visit Stanford campus today. Now it is 5:28 PM. I like to spend at least two hours on campus.