You Can Download and Read With File Format Pdf ePUB MOBI and Kindle Version. More Info==> Elements of Programming Interviews in Java: The Insiders' . Elements of Programming Interviews The Insiders' Guide Adnan Aziz .. A guide to reading C++ programs for Java developers is given on Page Source. lesforgesdessalles.infon. pdf - Ebook download as PDF File .pdf), Text File .txt) or read book .

Author: | NEVADA ANTINORO |

Language: | English, Spanish, Japanese |

Country: | Kosovo |

Genre: | Children & Youth |

Pages: | 282 |

Published (Last): | 05.02.2016 |

ISBN: | 787-1-43761-689-7 |

ePub File Size: | 29.69 MB |

PDF File Size: | 8.85 MB |

Distribution: | Free* [*Regsitration Required] |

Downloads: | 22342 |

Uploaded by: | YUKIKO |

Contribute to krishabhishek/test development by creating an account on GitHub. This document is a sampling of our book, Elements of Program- ming Interviews in Java (EPI). Its purpose is to provide examples of. This document is a sampling of our book, Elements of Programming. Interviews in chapters on the nontechnical aspects of interviewing. We'd love use library functions like stoi in C++, parseInt in Java, and int in Python.

Then time complexity of the algorithm above is 0 k. Specifically, you may notice that the maximum profit that can be made by selling on a specific day is determined by the minimum of the stock prices over the previous days. Test for corner cases: Refresh and try again. Let T be a binary tree on n nodes, with height h. Stacks and queues Stacks support last-in, first-out semantics for inserts and deletes, whereas queues are first-in, first-out.

Such companies do not have time to train new hires, and tend to hire candidates who are very fast learners or are already familiar with their technology stack, e. Mature consumer-facing company, e. Such companies have a deeper technology stack, much of which is developed in-house. They have the resources and the time to train a new hire. Enterprise-oriented company, e. Government contractor, e.

The tool chain and development practices at such companies tend to be very mature. General conversation Often interviewers will ask you questions about your past projects, such as a senior design project or an internship. The point of this conversation is to answer the following questions: Can the candidate clearly communicate a complex idea?

This is one of the most important skills for working in an engineering team. If you have a grand idea to redesign a big system, can you communicate it to your colleagues and bring them on board? It is crucial to practice how you will present your best work.

Being precise, clear, and having concrete examples can go a long way here. Candidates communicating in a language that is not their first language, should take extra care to speak slowly and make more use of the whiteboard to augment their words. We always want our colleagues to be excited, energetic, and inspiring to work with. Hence, when you are asked to describe a project from the past, it is best to pick something that you are passionate about rather than a project that was complex but did not interest you.

Is there a potential interest match with some project? The interviewer may gauge areas of strengths for a potential project match. If you know the requirements of the job, you may want to steer the conversation in that direction. Other advice Be honest: Nobody wants a colleague who falsely claims to have tested code or done a code review.

Dishonesty in an interview is a fast pass to an early exit. Similarly, if you have seen a problem before, you should say so. Be sure that it really is the same problem, and bear in mind you should describe a correct solution quickly if you claim to have solved it before.

Interviewers have been known to collude to ask the same question of a candidate to see if he tells the second interviewer about the first instance. An interviewer may feign ignorance on a topic he knows in depth to see if a candidate pretends to know it. Keep a positive spirit: A cheerful and optimistic attitude can go a long way. Candidates sometimes apologize in advance for a weak GPA, rusty coding skills, or not knowing the technology stack.

Their logic is that by being proactive they will somehow benefit from lowered expectations. Nothing can be further from the truth. It focuses attention on shortcomings. More generally, if you do not believe in yourself, you cannot expect others to believe in you.

Most software companies have a relaxed dress-code, and new grad- uates may wonder if they will look foolish by overdressing. The damage done when you are too casual is greater than the minor embarrassment you may feel at being overdressed. It is always a good idea to err on the side of caution and dress formally for your interviews.

At the minimum, be clean and well-groomed. Be aware of your body language: Think of a friend or coworker slouched all the time or absentmindedly doing things that may offend others. Work on your posture, eye contact and handshake, and remember to smile. Keep money and perks out of the interview: Money is a big element in any job but it is best left discussed with the HR division after an offer is made. The same is true for vacation time, day care support, and funding for conference travel.

Strategies For A Great Interview Stress interviews Some companies, primarily in the finance industry, make a practice of having one of the interviewers create a stressful situation for the candidate.

The stress may be injected technically, e. The goal is to see how a candidate reacts to such situations—does he fall apart, become belligerent, or get swayed easily. The guidelines in the previous section should help you through a stress interview. Bear in mind you will not know a priori if a particular interviewer will be conducting a stress interview. Learning from bad outcomes The reality is that not every interview results in a job offer. There are many reasons for not getting a particular job.

Some are technical: If this is the case, go back and solve that problem, as well as related problems. You can fail an interview for nontechnical reasons, e. The company may have decided not to hire in your area, or another candidate with similar ability but more relevant experience was hired. You will not get any feedback from a bad outcome, so it is your responsibility to try and piece together the causes. Negotiating an offer An offer is not an offer till it is on paper, with all the details filled in.

All offers are negotiable. When negotiating, remember there is nothing to be gained, and much to lose, by being rude. Being firm is not the same as being rude. To get the best possible offer, get multiple offers, and be flexible about the form of your compensation. For example, base salary is less flexible than stock options, sign- on bonus, relocation expenses, and Immigration and Naturalization Service INS filing costs.

Otherwise the recruiter will simply come back with a small increase in the sign-on bonus and claim to have met your request. Your HR contact is a professional negotiator, whose fiduciary duty is to the com- pany. This is what recruiters ElementsOfProgrammingInterviews. Strategies For A Great Interview 17 themselves are evaluated on internally.

The Wikipedia article on negotiation lays bare many tricks we have seen recruiters employ. One suggestion: If you are asked for something such as a copy of a competing offer , get something in return. Often it is better to bypass the HR contact and speak directly with the hiring manager. At the end of the day, remember your long term career is what counts, and joining a company that has a brighter future social-mobile vs. In this chapter we review practices that help interviewers identify a top hire.

We strongly recommend interviewees read it—knowing what an interviewer is looking for will help you present yourself better and increase the likelihood of a successful outcome. For someone at the beginning of their career, interviewing may feel like a huge responsibility. Hiring a bad candidate is expensive for the organization, not just because the hire is unproductive, but also because he is a drain on the productivity of his mentors and managers, and sets a bad example.

Firing someone is extremely painful as well as bad for to the morale of the team. On the other hand, discarding good candidates is problematic for a rapidly growing organization. Objective The ultimate goal of any interview is to determine the odds that a candidate will be a successful employee of the company. The ideal candidate is smart, dedicated, articulate, collegial, and gets things done quickly, both as an individual and in a team. Ideally, your interviews should be designed such that a good candidate scores 1.

One mistake, frequently made by novice interviewers, is to be indecisive. Unless the candidate walks on water or completely disappoints, the interviewer tries not to make a decision and scores the candidate somewhere in the middle. This means that the interview was a wasted effort.

A secondary objective of the interview process is to turn the candidate into a brand ambassador for the recruiting organization. Even if a candidate is not a good fit for the organization, he may know others who would be.

It is important for the candidate to have an overall positive experience during the process. Conducting An Interview 19 or insult the candidate over a mistake he made, but such behavior is depressingly common. Outside of a stress interview, the interviewer should work on making the candidate feel positively about the experience, and, by extension, the position and the company.

What to ask One important question you should ask yourself as an interviewer is how much training time your work environment allows. For a startup it is important that a new hire is productive from the first week, whereas a larger organization can budget for several months of training. Consequently, in a startup it is important to test the candidate on the specific technologies that he will use, in addition to his general abilities.

For a larger organization, it is reasonable not to emphasize domain knowledge and instead test candidates on data structures, algorithms, system design skills, and problem solving techniques. The justification for this is as follows. Algorithms, data structures, and system design underlie all software. It is often hidden in library calls. However, such code is usually the crucial component in terms of performance and correctness, and often serves to differentiate products. Furthermore, platforms and programming languages change quickly but a firm grasp of data structures, algo- rithms, and system design principles, will always be a foundational part of any successful software endeavor.

Finally, many of the most successful software compa- nies have hired based on ability and potential rather than experience or knowledge of specifics, underlying the effectiveness of this approach to selecting candidates. Most big organizations have a structured interview process where designated interviewers are responsible for probing specific areas. For example, you may be asked to evaluate the candidate on their coding skills, algorithm knowledge, critical thinking, or the ability to design complex systems.

This book gives interviewers access to a fairly large collection of problems to choose from. When selecting a problem keep the following in mind: No single point of failure—if you are going to ask just one question, you should not pick a problem where the candidate passes the interview if and only if he gets one particular insight. The best candidate may miss a simple insight, and a mediocre candidate may stumble across the right idea.

There should be at least two or three opportunities for the candidates to redeem themselves. For example, problems that can be solved by dynamic programming can almost always be solved through a greedy algorithm that is fast but suboptimum or a brute-force algorithm that is slow but optimum.

In such cases, even if the candidate cannot get the key insight, he can still demonstrate some problem solving abilities. Problem 6. Multiple possible solutions—if a given problem has multiple solutions, the chances of a good candidate coming up with a solution increases.

It also gives the interviewer more freedom to steer the candidate. A great candidate may finish ElementsOfProgrammingInterviews. Conducting An Interview with one solution quickly enough to discuss other approaches and the trade-offs between them.

For example, Problem Cover multiple areas—even if you are responsible for testing the candidate on algorithms, you could easily pick a problem that also exposes some aspects of design and software development. Calibrate on colleagues—interviewers often have an incorrect notion of how difficult a problem is for a thirty minute or one hour interview.

It is a good idea to check the appropriateness of a problem by asking one of your colleagues to solve it and seeing how much difficulty they have with it. No unnecessary domain knowledge—it is not a good idea to quiz a candidate on advanced graph algorithms if the job does not require it and the candidate does not claim any special knowledge of the field. Conducting the interview Conducting a good interview is akin to juggling.

Many things can happen in an interview that could help you reach a decision, so it is important to take notes. At the same time, it is important to keep a conversation going with the candidate and help him out if he gets stuck. Ideally, have a series of hints worked out beforehand, which can then be provided progressively as needed. Coming up with the right set of hints may require some thinking. You do not want to give away the problem, yet find a way for the candidate to make progress.

Here are situations that may throw you off: A candidate that gets stuck and shuts up: Some candidates get intimidated by the problem, the process, or the interviewer, and just shut up. It is important to put the candidate at ease, e. A verbose candidate: Candidates who go off on tangents and keep on talking without making progress render an interview ineffective.

Again, it is important to take control of the conversation. For example you could assert that a particular path will not make progress. An overconfident candidate: It is common to meet candidates who weaken their case by defending an incorrect answer.

To give the candidate a fair chance, it is important to demonstrate to him that he is making a mistake, and allow him to correct it. Scoring and reporting At the end of an interview, the interviewers usually have a good idea of how the candidate scored.

However, it is important to keep notes and revisit them before making a final decision. Whiteboard snapshots and samples of any code that the ElementsOfProgrammingInterviews.

Conducting An Interview 21 candidate wrote should also be recorded. You should standardize scoring based on which hints were given, how many questions the candidate was able to get to, etc.

Although isolated minor mistakes can be ignored, sometimes when you look at all the mistakes together, clear signs of weakness in certain areas may emerge, such as a lack of attention to detail and unfamiliarity with a language. When the right choice is not clear, wait for the next candidate instead of possibly making a bad hiring decision. The litmus test is to see if you would react positively to the candidate replacing a valuable member of your team. Einstein Developing problem solving skills is like learning to play a musical instrument— books and teachers can point you in the right direction, but only your hard work will take you there.

Just as a musician, you need to know underlying concepts, but theory is no substitute for practice. Great problem solvers have skills that cannot be rigorously formalized. We now introduce several patterns and illustrate them with examples. We have classified these patterns into the following categories: These patterns are summarized in Table 4. Keep in mind that you may have to use more than one of these patterns for a given problem.

The two most common criteria for comparing algorithms are runtime and memory usage. We briefly review complexity analysis and intractable problems at the end of this chapter. Data structure patterns A data structure is a particular way of storing and organizing related data items so that they can be manipulated efficiently. Usually, the correct selection of data structures is key to designing a good algorithm.

Different data structures are suited to different applications; some are highly specialized. For example, heaps are par- ticularly well-suited for algorithms that merge sorted data streams, while compiler implementations usually use hash tables to lookup identifiers.

The data structures described in this chapter are the ones commonly used. Other data structures, such as skip lists, treaps, Fibonacci heaps, tries, and disjoint-set data structures, have more specialized applications. Problem Solving Patterns 23 Solutions often require a combination of data structures. For example, tracking the most visited pages on a website involves a combination of a heap, a queue, a binary search tree, and a hash table.

Table 4. Data structure patterns. Data structure Key points Primitive types Know how int, char, double, etc. Arrays Fast access for element at an index, slow lookups un- less sorted and insertions. Be comfortable with no- tions of iteration, resizing, partitioning, merging, etc. Strings Know how strings are represented in memory.

Under- stand basic operators such as comparison, copying, matching, joining, splitting, etc. Lists Understand trade-offs with respect to arrays. Be com- fortable with iteration, insertion, and deletion within singly and doubly linked lists. Know how to imple- ment a list with dynamic allocation, and with arrays. Stacks and queues Understand insertion and deletion. Know array and linked list implementations. Binary trees Use for representing hierarchical data.

Heaps Key benefit: O 1 lookup find-max, O log n insertion, and O log n deletion of max. Node and array repre- sentations. Min-heap variant. Hash tables Key benefit: O 1 insertions, deletions and lookups. Key disadvantages: Understand implementation using array of buckets and collision chains. Know hash functions for integers, strings, objects. Understand importance of equals function.

Variants such as Bloom filters. Binary search trees Key benefit: O log n insertions, deletions, lookups, find-min, find-max, successor, predecessor when tree is balanced. Understand node fields, pointer imple- mentation. Be familiar with notion of balance, and op- erations maintaining balance.

Know how to augment a binary search tree, e. Primitive types You should be comfortable with the basic types chars, integers, doubles, etc. For example, Java has no unsigned integers, and the integer width is compiler- and machine-dependent in C. Problem Solving Patterns A common problem related to basic types is computing the number of bits set to 1 in an integer-valued variable x. To solve this problem you need to know how to manipulate individual bits in an integer. One straightforward approach is to iteratively test individual bits using an unsigned integer variable m initialized to 1.

Iteratively identify bits of x that are set to 1 by examining the bitwise AND of m with x, shifting m left one bit at a time.

The overall complexity is O n where n is the length of the integer. The variable y is 1 at exactly the lowest set bit of x; all other bits in y are 0. The time complexity is O s , where s is the number of bits set to 1 in x.

In practice, if the computation is done repeatedly, the most efficient approach would be to create a lookup table. In this case, we could use a entry integer-valued array P, such that P[i] is the number of bits set to 1 in i. If x is 64 bits, the result can be computed by decomposing x into 4 disjoint bit words, h3, h2, h1, and h0. The bit words are computed using bitmasks and shifting, e. Array lookup and insertion are fast, making arrays suitable for a variety of applications. Reading past the last element of an array is a common error, invariably with catastrophic consequences.

The following problem arises when optimizing quicksort: The key to the solution is to maintain two regions on opposite sides of the array that meet the requirements, and expand these regions one element at a time. Strings A string can be viewed as a special kind of array, namely one made out of charac- ters. We treat strings separately from arrays because certain operations which are commonly applied to strings—for example, comparison, joining, splitting, searching for substrings, replacing one string by another, parsing, etc.

Our solution to the look-and-say problem illustrates operations on strings. The look-and-say sequence begins with 1; the subsequent integers describe the dig- its appearing in the previous number in the sequence. The first eight integers in the look-and-say sequence are h1, 11, 21, , , , , i.

Problem Solving Patterns 25 The look-and-say problem entails computing the n-th integer in this sequence. Al- though the problem is cast in terms of integers, the string representation is far more convenient for counting digits. Lists An abstract data type ADT is a mathematical model for a class of data structures that have similar functionality. Strictly speaking, a list is an ADT, and not a data structure.

It implements an ordered collection of values, which may include repetitions. In the context of this book we view a list as a sequence of nodes where each node has a link to the next node in the sequence. In a doubly linked list each node also has a link to the prior node.

A list is similar to an array in that it contains objects in a linear order. The key differences are that inserting and deleting elements in a list has time complexity O 1. On the other hand, obtaining the k-th element in a list is expensive, having O n time complexity.

Lists are usually building blocks of more complex data structures. However, they can be the subject of tricky problems in their own right, as illustrated by the following: Given a singly linked list hl0 , l1 , l2 ,. Suppose you were asked to write a function that computes the zip of a list, with the constraint that it uses O 1 space. The operation of this function is illustrated in Figure 4.

L l0 l1 l2 l3 l4 0x 0x 0x 0x 0x a List before zipping. The number in hex below each node represents its address in memory.

L l0 l4 l1 l3 l2 0x 0x 0x 0x 0x b List after zipping. Note that nodes are reused—no memory has been allocated. Figure 4. Zipping a list. Stacks and queues Stacks support last-in, first-out semantics for inserts and deletes, whereas queues are first-in, first-out. Both are ADTs, and are commonly implemented using linked lists or arrays.

Similar to lists, stacks and queues are usually building blocks in a solution to a complex problem, but can make for interesting problems in their own right. As an example consider the problem of evaluating Reverse Polish notation expres- sions, i. A stack is ideal for this purpose—operands are pushed on the stack, and popped as operators are processed, with intermediate results being pushed back onto the stack.

Problem Solving Patterns Binary trees A binary tree is a data structure that is used to represent hierarchical relationships. Binary trees are the subject of Chapter Binary trees most commonly occur in the context of binary search trees, wherein keys are stored in a sorted fashion.

However, there are many other applications of binary trees. Consider a set of resources orga- nized as nodes in a binary tree. Processes need to lock resource nodes.

A node may be locked if and only if none of its descendants and ancestors are locked. Your task is to design and implement an application programming interface API for locking.

Naively implemented, the time complexity for these methods is O n , where n is the number of nodes. However, these can be made to run in time O 1 , O h , and O h , respectively, where h is the height of the tree, if nodes have a parent field. Heaps A heap is a data structure based on a binary tree. It efficiently implements an ADT called a priority queue.

A priority queue resembles a queue, with one difference: Each trade appears as a separate line containing information about that trade. Lines begin with an integer-valued timestamp, and lines within a file are sorted in increasing order of timestamp. Suppose you were asked to design an algorithm that combines the set of files into a single file R in which trades are sorted by timestamp.

This problem can be solved by a multistage merge process, but there is a trivial solution based on a min-heap data structure. Entries are trade-file pairs and are ordered by the timestamp of the trade. Initially, the min-heap contains the first trade from each file. Hash tables A hash table is a data structure used to store keys, optionally, with corresponding values.

Inserts, deletes and lookups run in O 1 time on average. One caveat is that these operations require a good hash function—a mapping from the set of all possible keys to the integers which is similar to a uniform random assignment. Another caveat is that if the number of keys that is to be stored is not known in advance then the hash table needs to be periodically resized, which, depending on how the resizing is implemented, can lead to some updates having O n complexity.

Suppose you were asked to write a function which takes a string s as input, and returns true if the characters in s can be permuted to form a string that is palindromic, i. Working through examples, you should see that a string is palindromic ElementsOfProgrammingInterviews. Problem Solving Patterns 27 if and only if each character appears an even number of times, with possibly a single exception, since this allows for pairing characters in the first and second halves.

A hash table makes performing this test trivial. We build a hash table H whose keys are characters, and corresponding values are the number of occurrences for that character. The hash table H is created with a single pass over the string. After computing the number of occurrences, we iterate over the key-value pairs in H. If more than one character has an odd count, we return false; otherwise, we return true.

Suppose you were asked to write an application that compares n programs for plagiarism. Specifically, your application is to break every program into overlapping character strings, each of length , and report on the number of strings that appear in each pair of programs. A hash table can be used to perform this check very efficiently if the right hash function is used.

Binary search trees Binary search trees BSTs are used to store objects that are comparable. BSTs are the subject of Chapter The underlying idea is to organize the objects in a binary tree in which the nodes satisfy the BST property on Page Insertion and deletion can be implemented so that the height of the BST is O log n , leading to fast O log n lookup and update times.

AVL trees and red-black trees are BST implementations that support this form of insertion and deletion. BSTs are a workhorse of data structures and can be used to solve almost every data structures problem reasonably efficiently. It is common to augment the BST to make it possible to manipulate more complicated data, e.

As an example application of BSTs, consider the following problem. You are given a set of line segments.

Each segment is a closed interval [li , ri ] of the x-axis, a color, and a height. For simplicity assume no two segments whose intervals overlap have the same height. When the x-axis is viewed from above the color at point x on the x-axis is the color of the highest segment that includes x. If no segment contains x, the color is blank. You are to implement a function that computes the sequence of colors as seen from the top.

The key idea is to sort the endpoints of the line segments and do a sweep from left-to-right. As we do the sweep, we maintain a list of line segments that intersect the current position as well as the highest line and its color.

Algorithm design patterns An algorithm is a step-by-step procedure for performing a calculation. We classify common algorithm design patterns in Table 4. Roughly speaking, each pattern corresponds to a design methodology.

An algorithm may use a combination of patterns. Problem Solving Patterns Table 4. Algorithm design patterns. Technique Key points Sorting Uncover some structure by sorting the input. Recursion If the structure of the input is defined in a recursive manner, design a recursive algorithm that follows the input definition.

Divide-and-conquer Divide the problem into two or more smaller inde- pendent subproblems and solve the original problem using solutions to the subproblems.

Dynamic program- Compute solutions for smaller instances of a given ming problem and use these solutions to construct a solution to the problem. Cache for performance. Greedy algorithms Compute a solution in stages, making choices that are locally optimum at step; these choices are never un- done. Sorting Certain problems become easier to understand, as well as solve, when the input is sorted. The solution to the calendar rendering problem entails taking a set of intervals and computing the maximum number of intervals whose intersection is nonempty.

However, once the interval endpoints have been sorted, it is easy to see that a point of maximum overlap can be determined by a linear time iteration through the endpoints. Often it is not obvious what to sort on—for example, we could have sorted the intervals on starting points rather than endpoints.

This sort sequence, which in some respects is more natural, does not work. However, some experimentation with it will, in all likelihood, lead to the correct criterion. Sorting is not appropriate when an O n or better algorithm is possible. Another good example of a problem where a total ordering is not required is the problem of rearranging elements in an array described on Page Furthermore, sorting can obfuscate the problem.

Recursion A recursive function consists of base cases and calls to the same function with different arguments. A recursive algorithm is often appropriate when the input is expressed using recursive rules, such as a computer grammar. More generally, searching, enumeration, divide-and-conquer, and decomposing a complex problem into a set of similar smaller instances are all scenarios where recursion may be suitable.

Problem Solving Patterns 29 String matching exemplifies the use of recursion. This problem can be solved by checking a number of cases based on the first one or two characters of the matching expression, and recursively matching the rest of the string.

Divide-and-conquer A divide-and-conquer algorithm works by decomposing a problem into two or more smaller independent subproblems until it gets to instances that are simple enough to be solved directly; the results from the subproblems are then combined.

More details and examples are given in Chapter 18; we illustrate the basic idea below. A triomino is formed by joining three unit-sized squares in an L-shape.

Mutilated chessboards. Problem Solving Patterns Divide-and-conquer is a good strategy for this problem. However, you will quickly see that this line of reasoning does not lead you anywhere. Now we can apply divide-and-conquer. Hence, a placement exists for any n that is a power of 2. Divide-and-conquer is usually implemented using recursion. However, the two concepts are not synonymous.

Recursion is more general—subproblems do not have to be of the same form. In addition to divide-and-conquer, we used the generalization principle above. The idea behind generalization is to find a problem that subsumes the given problem and is easier to solve.

Other examples of divide-and-conquer include solving the number of pairs of elements in an array that are out of sorted order and computing the closest pair of points in a set of points in the plane.

A key aspect of DP is maintaining a cache of solutions to subinstances. DP can be implemented recursively in which case the cache is typically a dynamic data structure such as a hash table or a BST , or iteratively in which case the cache is usually a one- or multi- dimensional array.

It is most natural to design a DP algorithm using recursion. Usually, but not always, it is more efficient to implement it using iteration. As an example of the power of DP, consider the problem of determining the number of combinations of 2, 3, and 7 point plays that can generate a score of Let C s be the number of combinations that can generate a score of s.

The recursion ends at small scores, specifically, when 1. This phenomenon results in the run time increasing exponentially with the size of the input. The solution is to store previously computed values of C in an array of length Details are given in Solution Greedy algorithms A greedy algorithm is one which makes decisions that are locally optimum and never changes them.

This strategy does not always yield the optimum solution. Furthermore, there may be multiple greedy algorithms for a given problem, and only some of them are optimum. For example, consider 2n cities on a line, half of which are white, and the other half are black. We want to map white to black cities in a one-to-one fashion so that the total length of the road sections required to connect paired cities is minimized. Multiple pairs of cities may share a single section of road, e. The most straightforward greedy algorithm for this problem is to scan through the white cities, and, for each white city, pair it with the closest unpaired black city.

This algorithm leads to suboptimum results. Consider the case where white cities are at 0 and at 3 and black cities are at 2 and at 5. If the straightforward greedy algorithm processes the white city at 3 first, it pairs it with 2, forcing the cities at 0 and 5 to pair up, leading to a road length of 5, whereas the pairing of cities at 0 and 2, and 3 and 5 leads to a road length of 4.

However, a slightly more sophisticated greedy algorithm does lead to optimum results: More succinctly, let W and B be the arrays of white and black city coordinates. Sort W and B, and pair W[i] with B[i]. We can prove this leads to an optimum pairing by induction. The idea is that the pairing for the first city must be optimum, since if it were to be paired with any other city, we could always change its pairing to be with the nearest black city without adding any road.

Chapter 18 contains a number of problems whose solutions employ greedy al- gorithms. Several problems in other chapters also use a greedy algorithm as a key subroutine. Invariants One common approach to designing an efficient algorithm is to use invariants. Briefly, an invariant is a condition that is true during execution of a program. This condition may be on the values of the variables of the program, or on the control ElementsOfProgrammingInterviews.

Problem Solving Patterns logic. A well-chosen invariant can be used to rule out potential solutions that are suboptimal or dominated by other solutions. An invariant can also be used to analyze a given algorithm, e. Here our focus is on designing algorithms with invariants, not analyzing them. As an example, consider the 2-sum problem.

We are given an array A of sorted integers, and a target value K. The brute-force algorithm for the 2-sum problem consists of a pair of nested for loops. Its complexity is O n2 , where n is the length of A.

While reducing time complexity to O n , this approach requires O n additional storage for H. Therefore, we can increment i, and preserve the invariant. At each step, we increment or decrement i or j. Since there are at most n steps, and each takes O 1 time, the time complexity is O n.

Correctness follows from the fact that the invariant never discards a value for i or j which could possibly be the index of an element which sums with another element to K. Identifying the right invariant is an art. Usually, it is arrived at by studying concrete examples and then making an educated guess. Often the first invariant is too strong, i. The efficient frontier can be viewed as an invariant.

For example, suppose we need to implement a stack that supports the max method, which is defined to return the largest value stored in the stack. We can associate for each entry in the stack the largest value stored at or below that entry.

Problem Solving Patterns 33 This makes returning the largest value in the stack trivial. The invariant is that the value associated for each entry is the largest value stored at or below that entry. The invariant certainly continues to hold after a pop. To ensure the invariant holds after a push, we compare the value v being pushed with the largest value m stored in the stack prior to the push which is the value associated with the entry currently at the top of the stack , and associate the entry being pushed with the larger of v and m.

Abstract analysis patterns The mathematician George Polya wrote a book How to Solve It that describes a number of heuristics for problem solving. Inspired by this work we present some heuristics, summarized in Table 4. Abstract analysis techniques. Analysis principle Key points Concrete examples Manually solve concrete instances of the problem and then build a general solution. Iterative refinement Most problems can be solved using a brute-force ap- proach.

Find such a solution and improve upon it. Reduction Use a well-known solution to some other problem as a subroutine. Graph modeling Describe the problem using a graph and solve it using an existing algorithm. Concrete examples Problems that seem difficult to solve in the abstract can become much more tractable when you examine concrete instances.

Specifically, the following types of inputs can offer tremendous insight: Problems 5. Consider the following problem. Five hundred closed doors along a corridor are numbered from 1 to A person walks through the corridor and opens each door.

Another person walks through the corridor and closes every alternate door. Continuing in this manner, the i-th person comes and toggles the state open or closed of every i-th door starting from Door i. You must determine exactly how many doors are open after the th person has walked through the corridor. It is difficult to solve this problem using an abstract approach, e.

However, if you try the same problem with 1, 2, 3, 4, 10, and 20 doors, it takes a short time to see ElementsOfProgrammingInterviews. Problem Solving Patterns that the doors that remain open are 1, 4, 9, 16,. The 10 doors case is illustrated in Figure 4. Now the pattern is obvious— the doors that remain open are those corresponding to the perfect squares.

Solution 5. Progressive updates to 10 doors. Case analysis In case analysis, a problem is divided into a number of separate cases, and analyzing each such case individually suffices to solve the initial problem. Cases do not have to be mutually exclusive; however, they must be exhaustive, that is cover all possi- bilities. These cases are individually easy to prove, and are exhaustive. Case analysis is commonly used in mathematics and games of strategy.

Here we consider an application of case analysis to algorithm design.

Your task is to identify the largest, second-largest, and third-largest integers in S using SORT5 to compare and sort subsets of S; furthermore, you must minimize the number of calls to SORT5. If all we had to compute was the largest integer in the set, the optimum approach would be to form five disjoint subsets S1 ,.

This takes six calls to SORT5 but leaves ambiguity about the second and third largest integers. It may seem like many additional calls to SORT5 are still needed.

Other terms are exhaustive search and generate-and-test. Often this algorithm can be refined to one that is faster. At the very least it may offer hints into the nature of the problem. One straightforward solution is to sort A and interleave the bottom and top halves of the sorted array. Both these approaches have the same time complexity as sorting, namely O n log n. You will soon realize that it is not necessary to sort A to achieve the desired configuration—you could simply rearrange the elements around the median, and then perform the interleaving.

Median finding can be performed in time O n , which is the overall time complexity of this approach. Finally, you may notice that the desired ordering is very local, and realize that it is not necessary to find the median. In code: However, it is much easier to implement and operates in an online fashion, i. As another example of iterative refinement, consider the problem of string search: Since s can occur at any offset in t, the brute-force solution is to test for a match at every offset.

This algorithm is perfectly correct; its time complexity is O nm , where n and m are the lengths of s and t. After trying some examples you may see that there are several ways to improve the time complexity of the brute-force algorithm.

As an example, if the character t[i] is not present in s you can advance the matching by n characters. Furthermore, this skipping works better if we match the search string from its end and work backwards.

These refinements will make the algorithm very fast linear time on random text and search strings; however, the worst-case complexity remains O nm. Problem Solving Patterns You can make the additional observation that a partial match of s that does not result in a full match implies other offsets that cannot lead to full matches. As another example, the brute-force solution to computing the maximum subarray sum for an integer array of length n is to compute the sum of all subarrays, which has O n3 time complexity.

This can be improved to O n2 by precomputing the sums of all the prefixes of the given arrays; this allows the sum of a subarray to be computed in O 1 time. The natural divide-and-conquer algorithm has an O n log n time complexity. Finally, one can observe that a maximum subarray must end at one of n indices, and the maximum subarray sum for a subarray ending at index i can be computed from previous maximum subarray sums, which leads to an O n algorithm.

Details are presented on Page Reduction Consider the problem of determining if one string is a rotation of the other, e. A natural approach may be to rotate the first string by every possible offset and then compare it with the second string. This algorithm would have quadratic time complexity. You may notice that this problem is quite similar to string search, which can be done in linear time, albeit using a somewhat complex algorithm.

Therefore, it is natural to try to reduce this problem to string search. Indeed, if we concatenate the second string with itself and search for the first string in the resulting string, we will find a match iff the two original strings are rotations of each other. This reduction yields a linear time algorithm for our problem. Usually, you try to reduce the given problem to an easier problem. Sometimes, however, you need to reduce a problem known to be difficult to the given prob- lem. This shows that the given problem is difficult, which justifies heuristics and approximate solutions.

Graph modeling Drawing pictures is a great way to brainstorm for a potential solution. If the relation- ships in a given problem can be represented using a graph, quite often the problem can be reduced to a well-known graph problem. For example, suppose you are given a set of exchange rates among currencies and you want to determine if an arbitrage exists, i.

Problem Solving Patterns 37 Table 4. An arbitrage is possible for this set of exchange rates: Exchange rates for seven major currencies.

If we can find a cycle in the graph with a positive weight, we would have found such a series of exchanges. Such a cycle can be solved using the Bellman-Ford algorithm. The solutions to the problems of painting a Boolean matrix Problem System design patterns Sometimes, you will be asked how to go about creating a set of services or a larger system on top of an algorithm that you have designed.

We summarize patterns that are useful for designing systems in Table 4. System design patterns. Design principle Key points Decomposition Split the functionality, architecture, and code into man- ageable, reusable components. Parallelism Decompose the problem into subproblems that can be solved independently on different machines. Caching Store computation and later look it up to save work. Decomposition Good decompositions are critical to successfully solving system-level design prob- lems.

Functionality, architecture, and code all benefit from decomposition. For example, in our solution to designing a system for online advertising, we decompose the goals into categories based on the stake holders. We decompose the architecture itself into a front-end and a back-end.

The front-end is divided into user management, web page design, reporting functionality, etc. The back-end is made up of middleware, storage, database, cron services, and algorithms for ranking ads. Problem Solving Patterns Decomposing code is a hallmark of object-oriented programming.

The subject of design patterns is concerned with finding good ways to achieve code-reuse. Broadly speaking, design patterns are grouped into creational, structural, and behavioral pat- terns. Many specific patterns are very natural—strategy objects, adapters, builders, etc. Freeman et al. Parallelism In the context of interview questions parallelism is useful when dealing with scale, i. Efficiency is typically measured in terms of central processing unit CPU time, ran- dom access memory RAM , network bandwidth, number of memory and database accesses, etc.

Consider the problem of sorting a petascale integer array. If we know the distri- bution of the numbers, the best approach would be to define equal-sized ranges of integers and send one range to one machine for sorting. The sorted numbers would just need to be concatenated in the correct order. If the distribution is not known then we can send equal-sized arbitrary subsets to each machine and then merge the sorted results, e.

The solution to Problem Caching Caching is a great tool whenever computations are repeated. For example, the central idea behind dynamic programming is caching results from intermediate computa- tions. Caching is also extremely useful when implementing a service that is expected to respond to many requests over time, and many requests are repeated. Workloads on web services exhibit this property. Complexity Analysis The run time of an algorithm depends on the size of its input.

One common approach to capture the run time dependency is by expressing asymptotic bounds on the worst- case run time as a function of the input size. The big-O notation indicates an upper bound on running time. As an example, searching an unsorted array of integers of length n, for a given integer, has an asymptotic complexity of O n since in the worst-case, the given integer may not be present.

Problem Solving Patterns 39 tries all numbers from 2 to the square root of the input number n. What is its complexity? In the best case, n is divisible by 2.

Generally speaking, if an algorithm has a run time that is a polynomial, i. Notable exceptions exist—for example, the simplex algo- rithm for linear programming is not polynomial but works very well in practice. On the other hand, the AKS primality testing algorithm has polynomial run time but the degree of the polynomial is too high for it to be competitive with randomized algorithms for primality testing.

Complexity theory is applied in a similar manner when analyzing the space requirements of an algorithm. Usually, the space needed to read in an instance is not included; otherwise, every algorithm would have O n space complexity. Several of our problems call for an algorithm that uses O 1 space. Conceptually, the memory used by such an algorithm should not depend on the size of the input instance. Specifically, it should be possible to implement the algorithm without dynamic memory allocation explicitly, or indirectly, e.

Furthermore, the maximum depth of the function call stack should also be a constant, independent of the input.

The standard algorithm for depth-first search of a graph is an example of an algorithm that does not perform any dynamic allocation, but uses the function call stack for implicit storage—its space complexity is not O 1.

A streaming algorithm is one in which the input is presented as a sequence of items and is examined in only a few passes typically just one. Keep in mind that some companies do not — ask these questions you should investigate the topics asked by companies you are interviewing at before investing too much time in them. Domain specific problems are conceptual and not meant to be coded.

Problems are specified as follows: We begin a simple brute-force solution. We outline variants problems whose formulation or solution is similar to the solved problem. We apply the program to a concrete input. The notation. We establish context. We analyze time and space complexity. Introduction to Algorithms by Cormen. You can always — communicate with us directly our contact information is on the website.

For the chapters at the end of the book. It also has links blog postings. Reader engagement Many of the best ideas in EPI came from readers like you. The review at the start of each chapter is not meant to be comprehensive and if you are not familiar with the material. Some of the material in the later chapters. Level and prerequisites We expect readers to be familiar with data structures and algorithms taught at the undergraduate level.

The companion website. There are dozens of such texts and our preference is to master one or two good books rather than superficially sample many. Algorithms by Dasgupta. The study guide. This is doable over 12 months if you solve a problem a day.

Exercise common sense when using Table 1. The preparation scenarios we consider are Hackathon a weekend entirely devoted to preparation.

If you need a data structure and algorithms refresher. The problems in EPI are meant to be representative of the problems you will encounter in an interview. Use them to hone your problem solving skills. Rote learning will likely lead to your giving a perfect solution to the wrong problem.

These aspects of interviewing are summarized in Table 1. If you have a graduate degree. Although an interviewer may occasionally ask a question directly from EPI. This information is summarized in Table 1. A large majority of the interview questions at Google. Since different candidates have different time constraints.

Chapter 25 contains a diverse collection of challenging questions. Prepare your resume using the guidelines on the facing page. Go for an on-site interview— this consists of a series of one-on-one interviews with engineers and managers.

A summary of nontechnical aspects of interviewing The Interview Lifecycle. You may be asked to submit code via a shared document or an online coding site such as ideone. Perform an initial phone screening. Identify companies that you are interested in. Table 1. For Scenario i. The screening may involve a homework assignment to be done before or after the conversation.

The on-site interview may be conducted over a video chat session. For each chapter. A r6sum6 needs to address HR staff.

Unless a problem is italicized. For anything involving interaction over a network. Use textbooks for reference only. The HR staff. First read Chapter 4. Receive offers these are usually a starting point for negotiations.

The people interviewing you and the hiring manager need to know what you've done that makes you special. The resume It always astonishes us to see candidates who've worked hard for at least four years in school. Most on-sites are half a day.

We recommend that you interview at as many places as you can without it taking away from your job or classes.

The experience will help you feel more comfortable with interviewing and you may discover you really like a company that you did not know much about. People reading your r6sum6 proceed in sequential order. Have friends review your r6sum6. It is better to get something written up quickly. As a rule. The r6sum6 should be of a high-quality: The most important points the ones that differentiate you from everyone else should come first..

Mock interviews Mock interviews are a great way of preparing for an interview. Have your friend take notes and give you Use few fonts. Have a clear statement of your objective. Over two pages is probably not a good idea. Maintaining a logical flow. Whenever possible. Include design documents as well as a link to your version control repository.

These samples may be class projects. Don't worry about wasting your contact's time employees often receive a referral bonus. If you can work at the company without requiring any special processing e. You should list significant class projects this also helps with keywords for HR. I would like to apply these abilities at XYZ.

As a consequence. At one company whose practices we are familiar with. Get a friend to ask you questions from EPI or any other source and solve them on a whiteboard.

Include contact information. You will cringe as you watch it. Some Java 1. You should be comfortable with the syntax used to instantiate an anonymous class. Make a video recording of the interview. In an actual interview. We also have a Junit test suite. Usually we declare helper classes as static inner classes of the top-level class that provides the solution. See Section 2 on Page 14 for more insights. Now we describe practices we follow in EPI which are industry-standard.

We wrote a very small number of utility functions. Best practices for interview code Now we describe practices we use in EPI that are not suitable for production code. Language review Programs are written in Java Some problems explicitly require you to write your own container classes.

Wherever possible. We have elected not to use popular third-party libraries. If you cannot find a friend. They are necessitated by the finite time constraints of an interview. Our test code lives within the mainO method of the top-level class.. Ask your friend to give hints when you get stuck. In addition to sharpening your problem solving and presentation skills. Apart from these. Tony Bevis' "Java Design Pattern Essentials" conveys the same content in a more succinct but less entertaining fashion.

NoSuchElementException when dequeing an empty queue. For design patterns. Note that programs for interviews are too short to take advantage of design patterns. Many programmers would use a generic Pair or Tuple class.. The definitive book for Java is — "Java: The Complete Reference" by Oracle Press this. Its primary drawback is its bulk. The guide is fairly straightforward it mostly addresses naming and spacing conventions.

This is not needed in an interview. You should spend your time making sure the program works. This is generally considered a best — — practice it enables code reuse via polymorphism but is not essential to use in an interview.. PORTER A typical one hour interview with a single interviewer consists of five minutes of introductions and questions about the candidate's r6sum6. Work on concrete examples: Consider the problem of determining the smallest amount of change that you cannot make with a given set of coins.

This is followed by five to fifteen minutes of questioning on basic programming concepts. Here are some things to keep in mind when this happens. Feel free to ask the interviewer what time and space complexity he would like in your solution. Clarify the question: A good way of clarifying the question is to state a concrete instance of the problem. The core of the interview is one or two detailed design questions where the candidate is expected to present a detailed solution on a whiteboard.

If a question seems exceptionally hard. Even if they are evasive. If you are told to implement an 0 n algorithm or use 0 1 space. Depending on the interviewer and the question. This problem may seem difficult at first. Approaching the problem No matter how clever and well prepared you are.

It is possible that he will refuse to specify these. Be warned that this strategy can sometimes be detrimental if it takes a long time to describe the brute-force approach. Add TODO comments for portions that you want to come back to. Focus on the top-level algorithm: It's OK to use functions that you will implement later. Advantages to this approach include: Presenting the solution Once you have an algorithm. Here are some things to keep in mind when presenting a solution.

Remember that a hash function should use exactly those fields which are used in the equality check. Even if you are not able to reach the solution. Spell out the brute-force solution: Writing on a whiteboard is much slower than on a Think out loud: One of the worst things you can do in an interview is to freeze up when solving the problem.

Make use of functions skip implementing anything that's trivial e. Do not reinvent the wheel unless asked to invent it.. Best practices for coding on a whiteboard are very different from best practices for coding on a production project. Patterns are described in Chapter 4. Patterns general reusable solutions to commonly occurring — problems can be a good way to approach a baffling problem. Specify that you will handle main algorithm first. On the one hand. A comparison function should be transitive.

Manage the whiteboard: You will likely use more of the board than you expect. It is always a good idea to think out loud and stay engaged. This will let you focus on the main part of the algorithm. Examples include finding a good data structure. On the other hand. Interviews are a great Test for comer cases: For many problems. C for arrays. Interviewers rarely penalize you for small syntax errors since modern IDE excel at handling these details.

You should clarify this assumption with the interviewer. Memory management: Generally speaking. If so. Interviewers are not capable of analyzing long programs. Candidates often tend to get function signatures wrong and it reflects poorly on them.

See if you can reuse space. Unless they are part of the problem statement. For fresh graduates. Once you are done writing your program. A good tip is that if your solution takes more than lines to code. You should use search and social networks to learn more about the people interviewing you. Don't forget to add code for checking the result. Letting your interviewers know that you have researched them helps break the ice and forms the impression that you are enthusiastic and will go the extra mile.

For example.. Assume valid inputs: In a production environment. It is important to systematically consider these possibilities. Have a convention for identifiers. If there is time. You should make the best use of this time by getting the information you would need and communicating to the interviewer that you are genuinely interested in the job. Enterprise-oriented company. It is crucial to practice how you will present your best work.

Being precise. Here is a brief classification. Such companies do not have time to train new hires.. Candidates communicating in a language that is not their first language.

Government contractor. You may also want to think of some concrete ideas around things you could do for the company. The tool chain and development practices at such companies tend to be very mature. In addition to knowing your interviewers. Is the candidate passionate about his work? We always want our colleagues to be excited. Prepare a list of questions in advance. Interviews usually end with the interviewers letting the candidates ask questions.

All companies want bright and motivated engineers. You should be ready to talk about what specifically appeals to you. Such companies have a deeper technology stack. If you feel passionately about your Mature consumer-facing company. The point of this conversation is to answer the following questions: Can the candidate clearly communicate a complex idea?

This is one of the most important skills for working in an engineering team. National Instruments: Based on your interaction with the interviewers. General conversation Often interviewers will ask you questions about your past projects. This extends to the team and company. If you have a grand idea to redesign a big system. Absolutely nothing is to be gained.

Be sure that it really is the same problem. An interviewer may feign ignorance on a topic he knows in depth to see if a candidate pretends to know it. At the minimum. Keep a positive spirit: A cheerful and optimistic attitude can go a long way. Dishonesty in an interview is a fast pass to an early exit. Interviewers have been known to collude to ask the same question of a candidate to see if he tells the second interviewer about the first instance.

Most software companies have a relaxed dress-code. Is there a potential interest match with some project? The interviewer may gauge areas of strengths for a potential project match. The damage done when you are too casual is greater than the minor embarrassment you may feel at being overdressed.

Keep in mind that because technology changes so fast many teams prefer a strong generalist. It focuses attention on shortcomings. Don't let these simple mistakes lead to your years of preparation going to waste.

Don't apologize: Candidates sometimes apologize in advance for a weak GPA. Keep money and perks out of the interview: Money is a big element in any job but it is best left discussed with the HR division after an offer is made. Other advice A bad mental and physical attitude can lead to a negative outcome. If you know the requirements of the job. Be aware of your body language: Think of a friend or coworker slouched all the time or absentmindedly doing things that may offend others.

Nothing can be further from the truth.

Their logic is that by being proactive they will somehow benefit from lowered expectations. It is always a good idea to err on the side of caution and dress formally for your interviews. Work on your posture. Be honest: Nobody wants a colleague who falsely claims to have tested code or done a code review. More generally. The same is true for vacation time. If your knowledge of Python extends only as far as having cut-and-paste sample code.

The stress may be injected technically. Bear in mind you will not know a priori if a particular interviewer will be conducting a stress interview. Remember the only mistakes are the ones you don't learn from.

Negotiating an offer An offer is not an offer till it is on paper. The guidelines in the previous section should help you through a stress interview. Your HR contact is a professional negotiator. When negotiating. All offers are negotiable. Learning from bad outcomes The reality is that not every interview results in a job offer. If this is the case. Otherwise the recruiter will simply come back with a small increase in the sign-on bonus and claim to have met your request.

You will not get any feedback from a bad outcome. To get the best possible offer. Being firm is not the same as being rude. This is what recruiters themselves are evaluated on internally..

Be concrete instead of just asking for more money. Some are technical: You can fail an interview for nontechnical reasons. He will know and use negotiating techniques such as reciprocity.

This can lead to your being asked questions on topics outside of the area of expertise you claimed on your r6sum6. The company may have decided not to hire in your area.

There are many reasons for not getting a particular job. The goal is to see how a candidate reacts to such situations does he fall apart. The Wikipedia article on negotiation lays bare many tricks we have seen recruiters employ. We have seen compensation packages bargained up to twice the initial offer. Stress interviews Some companies. Often it is better to bypass the HR contact and speak directly with the hiring manager. At the end of the day. One suggestion: If you are asked for something such as a copy of a competing offer.

Interviewers also have a moral responsibility not to unfairly crush the interviewee's dreams and aspirations. Unless the candidate walks on water or completely disappoints. A secondary objective of the interview process is to turn the candidate into a brand ambassador for the recruiting organization. Hiring a bad candidate is expensive for the organization. We — strongly recommend interviewees read it knowing what an interviewer is looking for will help you present yourself better and increase the likelihood of a successful outcome.

Objective The ultimate goal of any interview is to determine the odds that a candidate will be a successful employee of the company. Firing someone is extremely painful as well as bad for to the morale of the team. Even if a candidate is not a good fit for the organization.

It seems obvious that it is a bad idea for an interviewer to check email while the candidate is talking or insult the candidate over a mistake he made. It is important for the candidate to have an overall positive experience during the process. For someone at the beginning of their career. In this chapter we review practices that help interviewers identify a top hire. This means that the interview was a wasted effort. The ideal candidate is smart. One mistake. What to ask One important question you should ask yourself as an interviewer is how much training time your work environment allows.

For a startup it is important that a new hire is productive from the first week. Problem Algorithms and data structure code is usually a small component of a system dominated by the user interface UI.

For a larger organization. It is often hidden in library calls. The best candidate may miss a simple insight. It also gives the interviewer more freedom to steer the candidate. A great candidate may finish with one solution quickly enough to discuss other approaches and the trade-offs between them. In such cases. The justification for this is as follows. When selecting a problem keep the following in mind: There should be at least two or three opportunities for the candidates to redeem themselves.

Problem 6. This book gives interviewers access to a fairly large collection of problems to choose from. Most big organizations have a structured interview process where designated interviewers are responsible for probing specific areas. Outside of a stress interview. At a high level. The exception to this rule is if you want to test the candidate's response to stress. You should standardize scoring based on which hints were given.

Often the best way of doing this is to construct a test case where the candidate's solution breaks down. An overconfident candidate: It is common to meet candidates who weaken their case by defending an incorrect answer.

Many things can happen in an interview that could help you reach a decision. To give the candidate a fair chance. In such situations. It is a good idea to check the appropriateness of a problem by asking one of your colleagues to solve it and — seeing how much difficulty they have with it. Whiteboard snapshots and samples of any code that the candidate wrote should also be recorded.

Here are situations that may throw you off: A candidate that gets stuck and shuts up: Some candidates get intimidated by the problem. At the same time. For example you could assert that a particular path will not make progress. Although isolated minor mistakes can be ignored. Coming up with the right set of hints may require some thinking. Scoring and reporting At the end of an interview.

A verbose candidate: Candidates who go off on tangents and keep on talking without making progress render an interview ineffective. It is important to put the candidate at ease. No unnecessary domain knowledge it is not a good idea to quiz a candidate on advanced graph algorithms if the job does not require it and the candidate does not claim any special knowledge of the field.

You do not want to give away the problem. Conducting the interview Conducting a good interview is akin to juggling. When the right choice is not clear. The litmus test is to see if you would react positively to the candidate replacing a valuable member of your team.

Fibonacci heaps. Other data structures. The data structures described in this chapter are the ones commonly used. Just as a musician. See Solution Don't forget that the basic types differ among programming languages. Java has no unsigned integers. Solutions often require a combination of data structures.

Bear in mind developing problem solving skills is like learning to play a musical — instrument books and teachers can point you in the right direction. Different data structures are suited to different applications. It is precisely for this reason that EPI focuses on problems. Strings Know how strings are represented in memory. Heaps Key benefit: Lists Understand trade-offs with respect to arrays.

Binary search trees Key benefit: O logn insertions. Know hash functions for integers. Table 4. Hash tables Key benefit: The variable y is 1 at exactly the lowest bit of x that is 1. Understand node fields. Know array and linked list implementations. Be familiar with notion of balance. Another approach.

Know about depth. Data structures. Arrays Fast access for element at an index. O log n insertion. Understand implementation using array of buckets and collision chains. Key disadvantages: The overall complexity is 0 n where n is the length of the integer. Min-heap variant. Stacks and queues Recognize where last-in first-out stack and first-in first-out queue semantics are applicable. One straightforward approach is to iteratively test individual bits using the value 1 as a bitmask.

A common problem related to basic types is computing the number of bits set to 1 in an integer-valued variable x. Data structure Key points Primitive types Know how int. Binary trees Use for representing hierarchical data. In this case. The following problem arises when optimizing quicksort: Subtracting one from x underflows.

Consider sharpening your bit manipulation skills by writing expressions that use bitwise operators. If x is 64 bits. Now suppose x is 0. It is easy to introduce errors in code that manipulates bit-level data. Subtracting one from x changes the rightmost bit to zero and sets all the lower bits to one if you add one now. This calculation is robust it is — correct for unsigned and two's-complement representations. Reading past the last element of an array is a common error The time complexity is 0 s.

Problems involving manipulation of bit-level data are often asked in interviews. Details are given in Solution 6. The bit words are computed using bitmasks and shifting. The effect is to mask out the rightmost one. In practice. This fact can also be very useful. Computing the parity of an integer is closely related to counting the number of bits set to 1. The key to the solution is to maintain two regions on opposite sides of the array that meet the requirements.

Array lookup and insertion are fast. Details are given in Solution 7. Let L be a singly linked list. We treat strings separately from arrays because certain operations which are — — commonly applied to strings for example. Assume its nodes are numbered starting at 0. The look-and-say problem entails computing the nth integer in this sequence. Although the problem is cast in terms of integers. In the context of this book we view a list as a sequence of nodes where each node has a link to the next node in the sequence.

Our solution to the look-and-say problem illustrates operations on strings. Define the zip of L to be the list consisting of the interleaving of the nodes numbered 0. The look-and-say sequence begins with 1. Lists are usually building blocks of more complex data structures. Zipping a list.

Note that nodes are reused— no memory has been allocated. Figure 4. A list is similar to an array in that it contains objects in a linear order.. In a doubly linked list each node also has a link to the prior node. The operation of this program is illustrated in Figure 4. Suppose you were asked to write a program that computes the zip of a list.. The key differences are that inserting and deleting elements in a list has time complexity 0 1.

The number in hex below each node represents its address in memory. Details are given in Solution 9. Details are given in Solution This problem can be solved by a multistage merge process.

Binary trees most commonly occur in the context of binary search trees. Both are commonly implemented using linked lists or arrays. Suppose you were asked to design an algorithm that combines the set of files into a single file R in which trades are sorted by timestamp. Entries are trade-file pairs and are ordered by the timestamp of the trade. Binary trees are the subject of Chapter Let's say you are given a set of files. Similar to lists. Each trade appears as a separate line containing information about that trade.

Refer to Solution Naively implemented. Your task is to design and implement an application programming interface API for locking.

A reasonable API is one with a method for checking if a node is locked. A heap resembles a queue. A node may be locked if and only if none of its descendants and ancestors are locked. Lines begin with an integer-valued timestamp.

Processes need to lock resource nodes. A hash table is a data structure used to store keys, optionally, with corresponding values.

Inserts, deletes and lookups run in 0 1 time on average. One caveat is that — these operations require a good hash function a mapping from the set of all possible keys to the integers which is similar to a uniform random assignment. Another caveat is that if the number of keys that is to be stored is not known in advance then the hash table needs to be periodically resized, which, depending on how the resizing is implemented, can lead to some updates having 0 n complexity.

Suppose you were asked to write a program which takes a string s as input, and returns true if the characters in s can be permuted to form a string that is palindromic, i.

Working through examples, you should see that a string is palindromic if and only if each character appears an even number of times, with possibly a single exception, since this allows for pairing characters in the first and second halves. A hash table makes performing this test trivial.

We build a hash table H whose keys are characters, and corresponding values are the number of occurrences for that character. The hash table H is created with a single pass over the string. After computing the number of occurrences, we iterate over the key-value pairs in H.

If more than one character has an odd count, we return false; otherwise, we return true. Suppose you were asked to write an application that compares n programs for plagiarism. Specifically, your application is to break every program into overlapping character strings, each of length , and report on the number of strings that appear in each pair of programs. A hash table can be used to perform this check very efficiently if the right hash function is used.

Binary search trees BSTs are used to store objects that are comparable. BSTs are the subject of Chapter The underlying idea is to organize the objects in a binary tree in which the nodes satisfy the BST property on Page AVL trees and red-black trees are BST implementations that support this form of insertion and deletion.

BSTs are a workhorse of data structures and can be used to solve almost every data structures problem reasonably efficiently. It is common to augment the BST to make it possible to manipulate more complicated data, e. As an example application of BSTs, consider the following problem. You are given a set of line segments. Each segment is a closed interval [l,, r,] of the X-axis, a color, and a height. For simplicity assume no two segments whose intervals overlap have the same height.

When the X-axis is viewed from above the color at point x on the X-axis is the color of the highest segment that includes x. If no segment contains x,. You are to implement a function that computes the sequence of colors as seen from the top. The key idea is to sort the endpoints of the line segments and do a scan from left-to-right.

As we do the scan, we maintain a list of line segments that intersect the current position as well as the highest line and its color. To quickly lookup the highest line in a set of intersecting lines we keep the current set in a BST, with the interval's height as its key. We describe algorithm design patterns that we have found to be helpful in solving — interview problems. Keep in mind that you may have to use a combination of approaches to solve a problem. Analysis principle Key points Concrete examples Manually solve concrete instances of the problem and then build a general solution.

Find such a solution and improve upon it. Reduction Use a well-known solution to some other problem as a subroutine. Graph modeling Describe the problem using a graph and solve it using an existing algorithm. Specifically, the following types of inputs can offer tremendous insight: Problems 6.

Here is an example that shows the power of small concrete example analysis. Given a set of coins, there are some amounts of change that you may not be able to. Technique Key points Sorting Uncover some structure by sorting the input. Recursion If the structure of the input is defined in a recursive manner, design a recursive algorithm that follows the input definition.

Cache for performance. For example, if your coins are 1,1, 1,1, 1, 5, 10, 25, then the smallest value of change which cannot be made is Suppose you were asked to write a program which takes an array of positive integers and returns the smallest number which is not to the sum of a subset of elements of the array. A brute-force approach would be to enumerate all possible values, starting from 1, testing each value to see if it is the sum of array elements.

However, there is no simple efficient algorithm for checking if a given number is the sum of a subset of entries in the array. Heuristics may be employed, but the program will be unwieldy. We can get a great deal of insight from some small concrete examples. A trivial observation is that the smallest element in the array sets a lower bound on the change amount that can be constructed from that array, so if the array does not contain a 1, it cannot produce 1.

However, it may be possible to produce 2 without a 2 being present, since there can be 2 or more Is present. Continuing with a larger example, 1,2,4 produces 1,2, 3, 4, 5, 6, 7, and 1,2,5 produces 1, 2, 3, 5, 6, 7, 8. Now consider the effect of adding a new element u to the collection. Another observation is that the order of the elements within the array makes no difference to the amounts that are constructible.

However, by sorting the array allows us to stop when we reach a value that is too large to help, since all subsequent values. Specifically, let M[i-1] be the maximum constructible amount from the first i elements of the sorted array. To illustrate, suppose we are given 12, 2,1,15, 2, 4. This sorts to 1, 2, 2, 4,12, The maximum constructible amount we can make with the first element is 1. The third element, 2, allows us to produce all values up to and including 5.

The fourth element, 4, allows us to produce all values up to 9. We stop 10 is the smallest number that cannot be constructed. The code implementing this approach is shown below. The time complexity as a function of n, the length of the array, is 0 n log n to sort and 0 n to iterate, i. The smallest nonconstructible change problem on the current page, the Towers of Hanoi Cases do not have to be mutually exclusive; however, they must be exhaustive, that is cover all possibilities.

These cases are individually easy to prove, and are exhaustive. Case analysis is commonly used in mathematics and games of strategy.

Here we consider an application of case analysis to algorithm design. Your task is to identify the largest, second-largest, and third-largest integers in S using SORT 5 to compare and sort subsets of S; furthermore, you must minimize the number of calls to S0RT5. If all we had to compute was the largest integer in the set, the optimum approach would be to form five disjoint subsets Si, This takes six calls to S0RT5 but leaves ambiguity about the second and third largest integers. It may seem like many additional calls to SORT 5 are still needed.