• Home
  • Quick Bytes
  • Algorithms
  • Java
  • iOS
  • Android
  • Certifications
  • About Me

Lets Code Them Up!

  • Job Search Story 2k19

    May 1st, 2020

    The year was 2019, month was March, a Job Search Story began. I started this journey aspiring to be a Software Developer. And it took over a year,  660+ resume submissions, 150+ recruiter screens, 30+ coding assessments, and 10+ onsite interviews to finally land a job. Let’s go through this roller coaster together and learn from it for the future. 

    “Nothing in the world can take the place of persistence. Talent will not; nothing is more common than unsuccessful men with talent. Genius will not; unrewarded genius is almost a proverb. Education will not; the world is full of educated derelicts. Persistence and determination alone are omnipotent. The slogan “press on” has solved and will always solve the problems of the human race.” – Calvin Coolidge

    The search for the perfect resume

    First things first, I fixed my resume. I spent countless hours going through online resume builders like LiveCareer,  Resume Genius, ResumeBuild, VelvetJobs, Novoresume, etc. [Don’t ever do this again. Waste of time!] But I wasn’t satisfied with the results and would often discard them. I reached out to friends to get some sample resumes. They looked somewhat promising. So I used them to format my resume.

    One of my friends suggested to get a one-page resume and to have quantifiable accomplishments. A year ago my resume was around 2 pages. Then my search changed to learning more about the one-page resumes. And I found this template on CareerCup that made more sense to me than any out there on the internet. The process to convert my past experiences and skills to this format was a tough one. But somehow I crossed that bridge and had a resume. I got it verified by some friends.

    In hindsight, I would suggest a focus on improving my interviewing skills rather than the resume. Start practicing problems on leetcode. Or brush up on database concepts, practice SQL, learn system design, etc. 

    Now after going through Outco [More on that later], I would try to maintain an excel sheet of all the small and big projects I have been through, how I overcame any challenges that I faced during those projects and what was the end result. This helps in writing the best short quantifiable accomplishments and answer behavioral questions.

    The Job Hunt Begins

    Now the process of sending out resumes began. I got some recruiter’s calls which lead nowhere. I had some small consultancies reach out to me. They were ready to market my profile but required me to sign some documents giving them the sole right to represent me and taking away my freedom of applying by myself. I skipped them. After a few months of no job, in a moment of weakness, I did rethink my decision of skipping them. 

    After a lot of resume submissions (not that many!), I did get an interview at a local startup. And I failed this one terribly. That was the first wake up call and I started focusing more on my preparation. The second wake up call was when I failed Amazon’s Online Assessment. These led to spending more hours solving problems on leetcode, geekforgeeks and hackerrank to improve my coding skills. 

    Outco

    Things went stale for a few months. I reached out to many friends, relatives, and ex-colleagues to forward my resume to their companies. It was almost the end of August 2019 and almost six months had passed with no job. I was starting to get depressed on some days. Looking back, I know that a belief in myself and my dream of becoming a Software Engineer kept me sane and propelled me forward in spite of all the failures.

    “All our dreams can come true, if we have the courage to pursue them.” – Walt Disney

    I received an email from Outco about attending a demo class to learn about their program. The decision to join Outco’s program was made after I attended the session. Now the only thing remaining was to persuade others ( and to some extent even myself) that it is the right decision for me. It was a five-week program that would require me –

    • to attend every class.
    • to work hard on all the assignments.
    • to submit 25 resumes every week.
    • to take all the recruiter screens and coding assessments that come my way during those five weeks and more weeks and months ahead.
    • to keep preparing for an interview.
    • to attend weekly mock interview sessions after Outco.
    • all this along with taking care of an infant, cook, clean, manage a house.

    All this was tough. And everyone said so. Even I agreed. I thought, “Do I understand the commitment I am making? Will I be able to do it? Would I run away on the first sign of failure?”

    And I said to myself, “If I can do this, manage all this together, take help, this would be a preparation for the actual job that comes my way later. If my mother can manage an 8 to 8 job and raise both me and my sister, I can certainly do this.”

    Well, I did join the program.

    It turned out to be one of the best decisions in the past year. The Outco coaches helped in the following ways –

    • revamping the resume
    • forcing me to go back to find instances from projects that could be used as examples in interviews.
    • shared techniques to answer behavioral interview questions
    • shared methodology to follow while solving algorithm problems.

    Also, I became part of a community of people who were either like me or have been through the same situations. I learned a lot from interacting with other Software Engineers, Job seekers, and Coaches. 

    Post Outco

    The program changed my job search process entirely. Outco had this unusual requirement of submitting 25 resumes a week. Initially, I thought that was too much. But I started seeing the results in the first month itself. I was getting more recruiter screens than before. 

    Not only the resume submissions, but I also learned the importance of reaching out to people. In a way, I overcame my shyness. I sent emails and Linkedin messages to recruiters and engineers I have never spoken to. That increases the chances of getting recruiter screens.

    I started to apply to jobs where I met over 50% criteria sometimes, not waiting for the ones with a 100% match. This also increased the chances of getting interviews. Only applying to jobs with a 100% match is a mistake! 

    “You miss 100% of the shots you don’t take.”–Wayne Gretzky

    During the month of October, I had an onsite interview and got my first offer. I didn’t accept this one. I had another two onsites in November and December 2019. Both didn’t end in an offer.

    Then came January 2020 and I had another onsite which also didn’t end in an offer.

    With each and every interview, I did a post mortem. I analyzed what might have gone wrong, where I need to improve, what topics I need to brush up on and went to work on them.

    “Don’t be afraid to fail. Don’t waste energy trying to cover up failure. Learn from your failures and go on to the next challenge. It’s OK to fail. If you’re not failing, you’re not growing.” –H. Stanley Judd

    All these rejections were very hard on me. They hurt more than the automated ones. I have a folder in Gmail which has over 110+ rejection emails. I still rallied on.

    “The definition of insanity is doing the same thing over and over and expecting different results.” –Benjamin Franklin

    By January end, I was again losing hope of ever securing a job. And I was regretting not taking up the offer in October. Somehow I kept myself moving. I kept on submitting 25 resumes every week. I kept on giving recruiting screens and coding challenges that came my way.

    “Success consists of going from failure to failure without loss of enthusiasm.”–Winston Churchill

    How I prepared while taking care of an infant, now a toddler

    I am still trying to find the best way to manage both my work and my baby. Most of the time, I have help. When I attended class, either my husband or mother-in-law looked after her. I would cast system design/behavioral interview videos on TV while I was taking care of my daughter like feeding her or playing with her.

    I would study when she would nap in the afternoon. I would study either late at night when she is asleep or early morning. I mostly scheduled calls during her nap time. During recruiter screens and interviews, I would take help from my husband and mother-in-law.

    There were good days when I get to do a lot and then there were bad ones when no study happened. And I have made peace with that. I think the key to work with a child is to embrace the randomness. Have plans, but be prepared to throw them in the bin if your child decides to wake up early or wants your attention.

    Glimmer of Hope

    At the start of February, I got a LinkedIn message from Amazon’s recruiter. I had my second chance at Amazon. I worked very hard to pass Amazon’s OA this time. And then maintained the same level of preparation for the virtual onsite at the end of March.

    The Offer

    Voila! I got an offer to join Amazon in April. Initially, for two days I was in a state of disbelief. I couldn’t believe my dream of landing the job at one of the big 4 has come true.

    And here I am an SDE at Amazon.

    Special Thanks

    I would like to give special thanks to all these people who helped me throughout this job search journey –

    • Thank you, dear husband, for believing in me, motivating me, and helping me with our daughter.
    • Thank you, mother-in-law, for taking care of us, for helping me in taking care of our daughter and motivating me to never give up. 
    • Thank you, my parents and sister, for always motivating me to move forward in case of failures. 
    • Thank you all the coaches at Outco for improving my resume, giving feedback on both technical and behavioral questions.
    • Thank you all the peers for mock interviews with great feedbacks that improved my interviewing skills. 

    I hope, I remember all these for any endeavor I take up in the future. 

    Thank you, friends, for reading this. I would love to hear about your job search experiences and celebrate your successes. 

    Thanks again,

    Stay safe, Stay Healthy.

  • Backspace String Compare

    April 24th, 2020

    Given two strings S and T, return if they are equal when both are typed into empty text editors. # means a backspace character.

    Example 1:

    Input: S = "ab#c", T = "ad#c"
    Output: true
    Explanation: Both S and T become "ac".
    

    Example 2:

    Input: S = "ab##", T = "c#d#"
    Output: true
    Explanation: Both S and T become "".
    

    Example 3:

    Input: S = "a##c", T = "#a#c"
    Output: true
    Explanation: Both S and T become "c".
    

    Example 4:

    Input: S = "a#c", T = "b"
    Output: false
    Explanation: S becomes "c" while T becomes "b".
    

    Note:

    1. 1 <= S.length <= 200
    2. 1 <= T.length <= 200
    3. S and T only contain lowercase letters and '#' characters.

    Solution

    The solution is pretty simple to this one. We need to process each String and then compare the end result. To process each string we can use Stack, push an element is its not “#”, else pop the last element. Both time and space complexity for this solution will be O(m+n), if m and n are string lengths.

    class BackSpaceStringCompare {
        public boolean backspaceCompare(String S, String T) {
            
            // Find the string after processing both S and T and compare them
            return processString(S).equals(processString(T));
        }
        
        public String processString(String S){
            
            //Initialize a stack
            Stack&lt;Character> s = new Stack&lt;>();
            
            //Traverse through the String one character at a time
            for(char ch: S.toCharArray()){
                
                //if character is equal to #, then pop an element if stack is not empty
                if(ch == '#'){
                    if(!s.isEmpty())
                        s.pop();
                }
                
                // else push character to stack
                else
                    s.push(ch);
            }
            
            //return the string generated by stack
            return s.toString();
        }
    }
    
    

    Code – BackSpaceStringCompare.java

    Source – leetcode

  • Last Stone Weight

    April 17th, 2020

    We have a collection of stones, each stone has a positive integer weight.

    Each turn, we choose the two heaviest stones and smash them together.  Suppose the stones have weights x and y with x <= y.  The result of this smash is:

    • If x == y, both stones are totally destroyed;
    • If x != y, the stone of weight x is totally destroyed, and the stone of weight y has new weight y-x.

    At the end, there is at most 1 stone left.  Return the weight of this stone (or 0 if there are no stones left.)

    Example 1

    Input: [2,7,4,1,8,1]
    Output: 1
    Explanation: 
    We combine 7 and 8 to get 1 so the array converts to [2,4,1,1,1] then,
    we combine 2 and 4 to get 2 so the array converts to [2,1,1,1] then,
    we combine 2 and 1 to get 1 so the array converts to [1,1,1] then,
    we combine 1 and 1 to get 0 so the array converts to [1] then that's the value of last stone.
    

    Note:

    1. 1 <= stones.length <= 30
    2. 1 <= stones[i] <= 1000

    Solution

    The problem statement itself states that at each iteration we need to pick out the max two elements. So we need some sort of sorting to always get the max two elements.

    We can use the heap data structure to maintain a sorted state of elements and always pick out the max two. The algorithm would be like this.

    1. Add all the elements of the array to the max heap.
    2. Loop until heap size is greater than equal to two
      1. Take out the max two elements x, y;
      2. if they are not equal, insert  x – y back into the heap. 
    3. return 0 if the heap is empty, else return the top element of the heap.

    The time complexity is O(n log n) and space complexity is O(n) where n is the size of the array.

     

    class Solution {
        public int lastStoneWeight(int[] stones) {
            
            //Initialize Priority Queue to Max Heap
            PriorityQueue<Integer> pq = new PriorityQueue<Integer>((a, b) -> b - a);
            
            //add all elements of stones array to priority queue
            for(int stone: stones){
                pq.add(stone);
            }
            
            //Loop until the heap has atleast two elements.
            while(pq.size() >= 2){
                
                //Pop out the two max elements
                int x = pq.poll();
                int y = pq.poll();
                
                //Push the difference between the two values back into the queue
                if(x != y){
                    pq.add(x - y);
                }
            }
            
            // return 0 is queue is empty, else the top element
            return pq.isEmpty() ? 0 : pq.poll();
        }
    }
    

    Source – LeetCode

    Code – LastStoneWeight.java

     

  • Middle of the LinkedList

    April 9th, 2020

    Given a non-empty, singly linked list with the head node head, return a middle node of the linked list.

    If there are two middle nodes, return the second middle node.

    Example 1

    Input: [1,2,3,4,5]
    Output: Node 3 from this list (Serialization: [3,4,5])
    The returned node has value 3.  (The judge's serialization of this node is [3,4,5]).
    Note that we returned a ListNode object ans, such that:
    ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, and ans.next.next.next = NULL.
    

    Example 2

    Input: [1,2,3,4,5,6] 
    Output: Node 4 from this list (Serialization: [4,5,6]) Since the list has two middle nodes with values 3 and 4, we return the second one.
    

    Note:

    • The number of nodes in the given list will be between 1 and 100.

    Solution 1

    The immediate approach that came to my mind was as follows –

    1. Find the size of the linked list – One Traversal – O(n) [if n is the length of linkedlist]
    2. the middle will be (size of linkedlist/2)
    3. traverse until the (size of linkedlist/2) node and return it as the answer.

    This solution’s time complexity is O(n), but we are traversing through the linked list twice. And the space complexity os O(1).

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class MiddleNode1 {
        public ListNode middleNode(ListNode head) {
            
            // Initialize size of linkedlist, middle variable and current node
            int size = 0, middle = 0;
            ListNode current = head;
            
            // Traverse through linked list to find the size;
            while(current != null){
                current = current.next;
                size++;
            }
            
            // Calculate middle 
            middle = size/2;
            
            // Traverse linkedlist until i becomes middle
            int i = 0;
            current = head;
            while(i != middle){
                current = current.next;
                i++;
            }
            
            // return the middle node
            return current;
        }
    }
    

    Solution 2

    The next approach is little optimization over solution 1. We store the values of a node in a linked list and return the element to the middle index. This requires just one traversal. The time complexity for this solution is O(n), and space complexity is also O(n).

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class MiddleNode2 {
        public ListNode middleNode(ListNode head) {
            
            //Initialize the arraylist to store nodes
            ArrayList<ListNode> list = new ArrayList<>();
            ListNode current = head;
            
            // Traverse the linkedlist and add node to the list
            while(current != null){
                list.add(current);
                current = current.next;
            }
            
            // Find the middle index
            int middle = list.size()/2;
            
            // return the listnode at the middle index.
            return list.get(middle);
        }
    }
    

    Solution 3

    Using the fast and slow pointer method to find the middle element of a LinkedList. The idea is slow pointer moves one node at a time and the fast pointer moves two nodes at a time. The node where fast becomes null is the middle node. The time complexity for this solution is O(n) and space complexity is O(1).

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class MiddleNode3 {
        public ListNode middleNode(ListNode head) {
            
            //Initialize the fast and slow pointers
            ListNode fast = head, slow = head;
            
            // Traverse the linkedlist and update fast and slow pointers
            while(fast != null &amp;&amp; fast.next != null){
                slow = slow.next;
                fast = fast.next.next;
            }
        
            // return the slow pointer.
            return slow;
        }
    }
    
    

    Code – MiddleNode1.java, MiddleNode2.java, MiddleNode3.java

    Source – leetcode

  • Longest Substring Without Repeating Characters

    February 20th, 2020

    Given a string, find the length of the longest substring without repeating characters.

    Example 1:

    Input: "abcabcbb" 
    Output: 3 
    Explanation: The answer is "abc", with the length of 3.
    

    Example 2:

    Input: "bbbbb" 
    Output: 1 
    Explanation: The answer is "b", with the length of 1.
    

    Example 3:

    Input: "pwwkew" 
    Output: 3 
    Explanation: The answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
    

    Bruteforce Solution

    The BruteForce solution is to find all the substrings in the string and then check if they contain unique characters and updating the result with maximum of result and substring’s length. Finding all substrings of the strings require two loops and so that itself will be O(n^2). Checking if the founded substring is unique is another O(n) and so total time complexity is O(n^3), n being length of string.

    As we are using a HashSet to store the letters of the substring, the space complexity will be O(n), n being length of string.

     

    /*
    Time Complexity - O(n^3)
    Space Complexity - O(n)
    */
    
    class LengthOfLongestSubStringBrute {
        
        public int lengthOfLongestSubstring(String s) {
            
            //Initialize the length of result substring with zero
            int ans = 0;
            
            //Loop i from 0 to length of string and
            //loop j from i+1 to length of string 
            //to get each and every substring 
            for(int i = 0; i < s.length(); i++){
                for(int j = i+1; j <= s.length(); j++){
                    
                    //Check if substring has all unique characters
                    if(findIfUniqueSubstring(s, i, j)){
                        
                        //Update the result with the length of current substring
                        ans = Math.max(ans, j - i);
                    }
                }
            }
            
            //return the answer
            return ans;
        }
        
        public boolean findIfUniqueSubstring(String s, int start, int end){
            
            //Initialize a HashSet to store the characters
            HashSet<Character> set = new HashSet<Character>();
            
            //Loop from starting index to ending index
            for(int i = start; i < end; i++){
                char c = s.charAt(i);
                
                //if the set contains present character then return false
                //else add the character to set.
                if(set.contains(c))
                    return false;
                set.add(c);
            }
            
            //if all characters in substring are uniuq, return true;
            return true;
        }
    }
    

    Optimized Solution 1

    Using HashSet as sliding window we can reduce the complexity from O(n^3) to O(n).

    We start both i and j from 0. Add the jth character to HashSet if it is not present and update length to maximum of length and (j-i). Increment j. If jth character is present in HashSet, we remove the ith character and increment i. We continue this until both i and j are less than input length. The time and space complexity for this solution is O(n)

     

    /* 
    Time Complexity - O(n)
    Space Complexity - O(n)
    */
    
    class LengthOfLongestSubstringOptimized {
        
        public int lengthOfLongestSubstring(String s) {
            
            //Initialize the length of result substring with zero
            int ans = 0, i = 0, j = 0;
            
            //Initialize a HashSet to store the characters
            HashSet<Character> set = new HashSet<Character>();
            
            //Loop i from 0 to length of s and
            //loop j from 0 to length of s 
            //to get each and every substring 
            while(i < s.length() && j < s.length()){
                
                //if character at jth position is not present in set
                if(!set.contains(s.charAt(j))){
                    
                    //add the character to the set and set result 
                    //to length of substring till now.
                    set.add(s.charAt(j++));
                    ans = Math.max(ans, j-i);
                }
                else{
                    //remove the character at ith position and increment i;
                    set.remove(s.charAt(i++));
                }
            }
            //return the answer
            return ans;
        }
            
            
    }
    
    

    Optimized Solution 2

    This solution uses HashMap instead of HashSet. The time and space complexity is still O(n). Here we store the index of current character in hashmap. If we encounter a repeat character we update the value of i to the maximum of i and current characters(jth) index.

    /* 
    Time Complexity - O(n)
    Space Complexity - O(n)
    */
    
    class LengthOfLongestSubstringOptimized2 {
        
        public int lengthOfLongestSubstring(String s) {
            
            //Initialize the length of result substring with zero
            int ans = 0, i = 0, j = 0;
            
            //Initialize a HashMap to store the characters
            HashMap<Character, Integer> map = new HashMap<Character, Integer>();
            
            //loop j from 0 to length of s 
            //to get each and every substring 
            for(j = 0; j < s.length(); j++){
                
                //if map contains jth character
                if(map.containsKey(s.charAt(j))){
                    //update i to the index of 
                    i = Math.max(i, map.get(s.charAt(j)));
                }
                
                //put the character in map with index
                map.put(s.charAt(j), j+1);
                ans = Math.max(ans, j-i+1);
            }
            
            //return the answer
            return ans;
        }
            
            
    }
    

    Source – LeetCode

    SourceCode – Github

  • SQL – PADS

    February 9th, 2020

    Generate the following two result sets:

    1. Query an alphabetically ordered list of all names in OCCUPATIONS, immediately followed by the first letter of each profession as a parenthetical (i.e.: enclosed in parentheses). For example: AnActorName(A), ADoctorName(D), AProfessorName(P), and ASingerName(S).
    2. Query the number of ocurrences of each occupation in OCCUPATIONS. Sort the occurrences in ascending order, and output them in the following format.   There are a total of [occupation_count] [occupation]s. where [occupation_count] is the number of occurrences of an occupation in OCCUPATIONS and [occupation] is the lowercase occupation name. If more than one Occupation has the same [occupation_count], they should be ordered alphabetically.

    Note: There will be at least two entries in the table for each type of occupation.

    Input Format

    The OCCUPATIONS table is described as follows: 

     

    Occupation will only contain one of the following values: Doctor, Professor, Singer or Actor.

    Sample Input

    An OCCUPATIONS table that contains the following records:

    Sample Output

    Ashely(P) 
    Christeen(P) 
    Jane(A) 
    Jenny(D) 
    Julia(A) 
    Ketty(P) 
    Maria(A) 
    Meera(S) 
    Priya(S) 
    Samantha(D) 
    There are a total of 2 doctors. 
    There are a total of 2 singers. 
    There are a total of 3 actors. 
    There are a total of 3 professors.
    

    Solution

    First Query

    1. The first query wants to display the Name of the person and only the first letter of the Occupation.
    2. To find the first letter of occupation we can use LEFT() function of MYSQL and SUBSTR() function of Oracle.
    3. To give output as “Name(O)”, we can use CONCAT() function in MYSQL and CONCAT() function or concantenation operator “||” in ORACLE.
    4. We need to order the result by alphabetically by name, for that we can use ORDER BY NAME

     

    MySQL

    SELECT CONCAT(NAME,'(',LEFT(OCCUPATION, 1),')') 
    FROM OCCUPATIONS 
    ORDER BY NAME;
    

    Oracle

    SELECT NAME || '(' || SUBSTR(OCCUPATION, 0, 1) || ')' 
    FROM OCCUPATIONS 
    ORDER BY NAME;
    

    Second Query

    1. To find the number of occurrences of each occupation, we can use the COUNT(*) function along with GROUP BY clause.
    2. To give output as “There are a total of 6 doctors.”, we can use CONCAT() function in MYSQL and CONCAT() function or concantenation operator “||” in ORACLE.
    3. And we can use LOWER() function to convert “Doctor” to “doctor”.
    4. To order by number of occurrences of occupation first and alphabetically by OCCUPATION second we can use ORDER BY COUNT(*), OCCUPATION.

     

    MySQL

    SELECT CONCAT('There are a total of ', COUNT(*), ' ', LOWER(OCCUPATION), 's.') 
    FROM OCCUPATIONS 
    GROUP BY OCCUPATION 
    ORDER BY COUNT(*), OCCUPATION;
    

    Oracle

    SELECT 'There are a total of ' || COUNT(*) || ' ' || LOWER(OCCUPATION) || 's.' 
    FROM OCCUPATIONS 
    GROUP BY OCCUPATION 
    ORDER BY COUNT(*), OCCUPATION;
    

    Source – Hackerrank

←Previous Page
1 … 9 10 11 12 13 … 22
Next Page→

Proudly powered by WordPress