27.10.2014 Views

Cracking the Coding Interview, 4 Edition - 150 Programming Interview Questions and Solutions

Cracking the Coding Interview, 4 Edition - 150 Programming Interview Questions and Solutions

Cracking the Coding Interview, 4 Edition - 150 Programming Interview Questions and Solutions

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Solutions</strong> to Chapter 20 | Hard<br />

20.2 Write a method to shuffle a deck of cards. It must be a perfect shuffle - in o<strong>the</strong>r words,<br />

each 52! permutations of <strong>the</strong> deck has to be equally likely. Assume that you are given<br />

a r<strong>and</strong>om number generator which is perfect.<br />

SOLUTION<br />

pg 91<br />

This is a very well known interview question, <strong>and</strong> a well known algorithm. If you aren’t one<br />

of <strong>the</strong> lucky few to have already know this algorithm, read on.<br />

Let’s start with a brute force approach: we could r<strong>and</strong>omly selecting items <strong>and</strong> put <strong>the</strong>m into<br />

a new array. We must make sure that we don’t pick <strong>the</strong> same item twice though by somehow<br />

marking <strong>the</strong> node as dead.<br />

Array: [1] [2] [3] [4] [5]<br />

R<strong>and</strong>omly select 4: [4] [?] [?] [?] [?]<br />

Mark element as dead: [1] [2] [3] [X] [5]<br />

The tricky part is, how do we mark [4] as dead such that we prevent that element from being<br />

picked again? One way to do it is to swap <strong>the</strong> now-dead [4] with <strong>the</strong> first element in <strong>the</strong><br />

array:<br />

Array: [1] [2] [3] [4] [5]<br />

R<strong>and</strong>omly select 4: [4] [?] [?] [?] [?]<br />

Swap dead element: [X] [2] [3] [1] [5]<br />

Array: [X] [2] [3] [1] [5]<br />

R<strong>and</strong>omly select 3: [4] [3] [?] [?] [?]<br />

Swap dead element: [X] [X] [2] [1] [5]<br />

By doing it this way, it’s much easier for <strong>the</strong> algorithm to “know” that <strong>the</strong> first k elements are<br />

dead than that <strong>the</strong> third, fourth, nineth, etc elements are dead. We can also optimize this by<br />

merging <strong>the</strong> shuffled array <strong>and</strong> <strong>the</strong> original array.<br />

R<strong>and</strong>omly select 4: [4] [2] [3] [1] [5]<br />

R<strong>and</strong>omly select 3: [4] [3] [2] [1] [5]<br />

This is an easy algorithm to implement iteratively:<br />

1 public static void shuffleArray(int[] cards) {<br />

2 int temp, index;<br />

3 for (int i = 0; i < cards.length; i++){<br />

4 index = (int) (Math.r<strong>and</strong>om() * (cards.length - i)) + i;<br />

5 temp = cards[i];<br />

6 cards[i] = cards[index];<br />

7 cards[index] = temp;<br />

8 }<br />

9 }<br />

2 8 1<br />

<strong>Cracking</strong> <strong>the</strong> <strong>Coding</strong> <strong>Interview</strong> | Additional Review Problems

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!