Generating Prime


public boolean isPrime(int number) {
      if (number == 1)
            return false;
      if (number == 2)
            return true;
      if (number % 2 == 0)
            return false;
      for (int d = 3; d <= (int) Math.sqrt(number); d++)
            if (number % d == 0)
                  return false;
      return true;
}
for (int d = 3; d <= (int)sqrt((double)number); d++)
However since we have already tested for even numbers, i.e. number % 2, we can safely increment the count to d + 2:
for (int d = 3; d <= (int)sqrt((double)number); d = d + 2)
Sieve of Eratosthenes
http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
The multiples of a given prime are generated as a sequence of numbers starting from that prime, with constant difference between them which is equal to that prime.

Simple Version:
http://introcs.cs.princeton.edu/java/14array/PrimeSieve.java.html
public static void main(String[] args) { 
 int N = Integer.parseInt(args[0]);
 boolean[] isPrime = new boolean[N + 1]; // can be changed to use BitSet for space efficient
 for (int i = 2; i <= N; i++) {
   isPrime[i] = true;
 }

 // mark non-primes <= N using Sieve of Eratosthenes
 for (int i = 2; i*i <= N; i++) {

   // if i is prime, then mark multiples of i as nonprime
   // suffices to consider mutiples i, i+1, ..., N/i
   if (isPrime[i]) {
     for (int j = i; i*j <= N; j++) {
       isPrime[i*j] = false;
     }
   }
 }

 // count primes
 int primes = 0;
 for (int i = 2; i <= N; i++) {
   if (isPrime[i]) primes++;
 }
 System.out.println("The number of primes <= " + N + " is " + primes);
}
位操作与空间压缩
在上面程序是用bool数组来作标记的,bool型数据占1个字节(8位),因此用位操作来压缩下空间占用将会使空间的占用减少八分之七。
int flag[MAXN / 32 + 1];
int primes[MAXN / 3 + 1], pi;
void GetPrime_1()
{
 int i, j;
 pi = 0;
 memset(flag, 0, sizeof(flag));
 for (i = 2; i < MAXN; i++)
  if (!((flag[i / 32] >> (i % 32)) & 1))
  {
   primes[pi++] = i;
   for (j = i; j < MAXN; j += i)
    flag[j / 32] |= (1 << (j % 32));
  }
}
http://en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/Prime_number_generation
Use BitSet to save memory space.
public class Sieve
{
 private BitSet sieve;
 private Sieve() {}
 private Sieve(int size) {
   sieve = new BitSet((size+1)/2);
 }
 private boolean is_composite(int k)
 {
   assert k >= 3 && (k % 2) == 1;
   return sieve.get((k-3)/2);
 }
 private void set_composite(int k)
 {
   assert k >= 3 && (k % 2) == 1;
   sieve.set((k-3)/2);
 }
 public static List<Integer> sieve_of_eratosthenes(int max)
 {
   Sieve sieve = new Sieve(max + 1); // +1 to include max itself
   for (int i = 3; i*i <= max; i += 2) {
     if (sieve.is_composite(i))
       continue;

     // We increment by 2*i to skip even multiples of i
     for (int multiple_i = i*i; multiple_i <= max; multiple_i += 2*i)
       sieve.set_composite(multiple_i);

   }
   List<Integer> primes = new ArrayList<Integer>();
   primes.add(2);
   for (int i = 3; i <= max; i += 2)
     if (!sieve.is_composite(i))
       primes.add(i);

   return primes;
 }
}

Sieve of Atkin- Faster but hard to understand
http://en.wikipedia.org/wiki/Sieve_of_Atkin
the sieve of Atkin is a fast, modern algorithm for finding all prime numbers up to a specified integer. It is an optimized version of the ancient sieve of Eratosthenes which does some preliminary work and then marks off multiples of the square of each prime, rather than multiples of the prime itself. 


http://bcbutler.com/Java_Tuts/java_sieve_of_atkins.php
public class AtkinSieve {
 public static int[] findPrimes(int arraySize) {
   boolean[] isPrime = new boolean[arraySize + 1];
   double sqrt = Math.sqrt(arraySize);

   for (int x = 1; x <= sqrt; x++) {
     for (int y = 1; y <= sqrt; y++) {
       int n = 4 * x * x + y * y;
       if (n <= arraySize && (n % 12 == 1 || n % 12 == 5)) {
         isPrime[n] = !isPrime[n];
       }

       n = 3 * x * x + y * y;
       if (n <= arraySize && (n % 12 == 7)) {
         isPrime[n] = !isPrime[n];
       }

       n = 3 * x * x - y * y;
       if (x > y && (n <= arraySize) && (n % 12 == 11)) {
         isPrime[n] = !isPrime[n];
       }
     }
   }
   for (int n = 5; n <= sqrt; n++) {
     if (isPrime[n]) {
       int s = n * n;
       for (int k = s; k <= arraySize; k += s) {
         isPrime[k] = false;
       }
     }
   }
   int[] primes = new int[arraySize];
   int found = 0;
   if (arraySize > 2) {
     primes[found++] = 2;
   }
   if (arraySize > 3) {
     primes[found++] = 3;
   }
   for (int n = 5; n <= arraySize; n += 2) {
     if (isPrime[n]) {
       primes[found++] = n;
     }
   }
   return Arrays.copyOf(primes, found);
 }
}

Levenshtein distance


Levenshtein distance is a string metric for measuring the difference between two sequences. Informally, the Levenshtein distance between two words is the minimum number of single-character edits (i.e. insertions, deletions or substitutions) required to change one word into the other.
Iterate Version:
http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#Java
public class LevenshteinDistance {                                               
    private static int minimum(int a, int b, int c) {                            
        return Math.min(Math.min(a, b), c);                                      
    }                                                                            
 
    public static int computeLevenshteinDistance(String str1,String str2) {      
        int[][] distance = new int[str1.length() + 1][str2.length() + 1];        
 
        for (int i = 0; i <= str1.length(); i++)                                 
            distance[i][0] = i;                                                  
        for (int j = 1; j <= str2.length(); j++)                                 
            distance[0][j] = j;                                                  
 
        for (int i = 1; i <= str1.length(); i++)                                 
            for (int j = 1; j <= str2.length(); j++)                             
                distance[i][j] = minimum(                                        
                        distance[i - 1][j] + 1,                                  
                        distance[i][j - 1] + 1,                                  
                        distance[i - 1][j - 1] + ((str1.charAt(i - 1) == str2.charAt(j - 1)) ? 0 : 1));
 
        return distance[str1.length()][str2.length()];                           
    }                                                                            
}
Not recursive and faster 
public int LevenshteinDistance (String s0, String s1) {                          
    int len0 = s0.length() + 1;                                                  
    int len1 = s1.length() + 1;                                                 
    // the array of distances         
    int[] cost = new int[len0];      
    int[] newcost = new int[len0];        
    // initial cost of skipping prefix in String s0            
    for (int i = 0; i < len0; i++) cost[i] = i;       
    // dynamicaly computing the array of distances     
    // transformation cost for each letter in s1      
    for (int j = 1; j < len1; j++) {   
        // initial cost of skipping prefix in String s1   
        newcost[0] = j;       
        // transformation cost for each letter in s0    
        for(int i = 1; i < len0; i++) {     
            // matching current letters in both strings    
            int match = (s0.charAt(i - 1) == s1.charAt(j - 1)) ? 0 : 1;     
            // computing cost for each transformation   
            int cost_replace = cost[i - 1] + match; 
            int cost_insert  = cost[i] + 1;     
            int cost_delete  = newcost[i - 1] + 1;    
            // keep minimum cost                                                    
            newcost[i] = Math.min(Math.min(cost_insert, cost_delete), cost_replace);
        }
        // swap cost/newcost arrays      
        int[] swap = cost; cost = newcost; newcost = swap;   
    }                          
    // the distance is the cost for transforming all letters in both strings    
    return cost[len0 - 1];     
}
http://rosettacode.org/wiki/Levenshtein_distance#Java
    public static int distance(String a, String b) {
        a = a.toLowerCase();
        b = b.toLowerCase();
        // i == 0
        int [] costs = new int [b.length() + 1];
        for (int j = 0; j < costs.length; j++)
            costs[j] = j;
        for (int i = 1; i <= a.length(); i++) {
            // j == 0; nw = lev(i - 1, j)
            costs[0] = i;
            int nw = i - 1;
            for (int j = 1; j <= b.length(); j++) {
                int cj = Math.min(1 + Math.min(costs[j], costs[j - 1]), a.charAt(i - 1) == b.charAt(j - 1) ? nw : nw + 1);
                nw = costs[j];
                costs[j] = cj;
            }
        }
        return costs[b.length()];
    }
Recursion Version:
http://rosettacode.org/wiki/Levenshtein_distance#Java
    public static int levenshtein(String s, String t){
        /* if either string is empty, difference is inserting all chars 
         * from the other
         */
        if(s.length() == 0) return t.length();
        if(t.length() == 0) return s.length();
 
        /* if first letters are the same, the difference is whatever is
         * required to edit the rest of the strings
         */
        if(s.charAt(0) == t.charAt(0))
            return levenshtein(s.substring(1), t.substring(1));
 
        /* else try:
         *      changing first letter of s to that of t,
         *      remove first letter of s, or
         *      remove first letter of t
         */
        int a = levenshtein(s.substring(1), t.substring(1));
        int b = levenshtein(s, t.substring(1));
        int c = levenshtein(s.substring(1), t);
 
        if(a > b) a = b;
        if(a > c) a = c;
 
        //any of which is 1 edit plus editing the rest of the strings
        return a + 1;
    }
EPI Java Solution
LevenshteinDistance.java

Merge Sort


Merge sort on linkedlist
http://javabypatel.blogspot.in/2015/12/merge-sort-linked-list.html
 private Node mergeSortLinkList(Node startNode){
   
  //Break the list until list is null or only 1 element is present in List.
  if(startNode==null || startNode.getNext()==null){
   return startNode;
  }
  //Break the linklist into 2 list.
  //Finding Middle node and then breaking the Linled list in 2 parts.
  //Now 2 list are, 1st list from start to middle and 2nd list from middle+1 to last.
   
  Node middle = getMiddle(startNode);
  Node nextOfMiddle = middle.getNext();
  middle.setNext(null);
  //Again breaking the List until there is only 1 element in each list.
  Node left = mergeSortLinkList(startNode);
  Node right = mergeSortLinkList(nextOfMiddle);
  //Once complete list is divided and contains only single element,
  //Start merging left and right half by sorting them and passing Sorted list further.
  Node sortedList = mergeTwoListRecursive(left, right);
   
  return sortedList;
 }
 //Recursive Approach for Merging Two Sorted List
 private Node mergeTwoListRecursive(Node leftStart, Node rightStart){
  if(leftStart==null)
   return rightStart;
   
  if(rightStart==null)
   return leftStart;
  Node temp=null;
   
  if(leftStart.getData()<rightStart.getData()){
   temp=leftStart;
   temp.setNext(mergeTwoListRecursive(leftStart.getNext(), rightStart));
  }else{
   temp=rightStart;
   temp.setNext(mergeTwoListRecursive(leftStart, rightStart.getNext()));
  }
  return temp;
 }
 private Node getMiddle(Node startNode) {
  if(startNode==null){
   return startNode;
  }
  Node pointer1=startNode;
  Node pointer2=startNode;
   
  while(pointer2!=null && pointer2.getNext()!=null && pointer2.getNext().getNext()!=null){
   pointer1 = pointer1.getNext();
   pointer2 = pointer2.getNext().getNext();
  }
  return pointer1;
 }

 //Iterative Approach for Merging Two Sorted List
 private Node mergeTwoListIterative(Node leftStart, Node rightStart) {
  Node merged=null;
  Node temp=null;
  //To keep track of last element, so that we don't need to iterate for adding the element at last of
  //list when either LeftStart or rightStart is NULL.
  Node lastAddedNode = null;
  while(leftStart!=null && rightStart!=null){
   if(leftStart.getData()>rightStart.getData()){
    temp = new Node(rightStart.getData());
    rightStart=rightStart.getNext();
   }else{
    temp = new Node(leftStart.getData());
    leftStart=leftStart.getNext();
   }
   if(merged==null){
    merged=temp;
   }else{
    lastAddedNode.setNext(temp);    
   }
   lastAddedNode=temp;
  }
  if(leftStart!=null){
   lastAddedNode.setNext(leftStart);
  }else{
   lastAddedNode.setNext(rightStart);
  }
   
  return merged;
 }
https://www.cs.cmu.edu/~adamchik/15-121/lectures/Sorting%20Algorithms/code/MergeSort.java
 public static void mergeSort(Comparable [ ] a)
 {
  Comparable[] tmp = new Comparable[a.length];
  mergeSort(a, tmp,  0,  a.length - 1);
 }


 private static void mergeSort(Comparable [ ] a, Comparable [ ] tmp, int left, int right)
 {
  if( left < right )
  {
   int center = (left + right) / 2;
   mergeSort(a, tmp, left, center);
   mergeSort(a, tmp, center + 1, right);
   merge(a, tmp, left, center + 1, right);
  }
 }


    private static void merge(Comparable[ ] a, Comparable[ ] tmp, int left, int right, int rightEnd )
    {
        int leftEnd = right - 1;
        int k = left;
        int num = rightEnd - left + 1;

        while(left <= leftEnd && right <= rightEnd)
            if(a[left].compareTo(a[right]) <= 0)
                tmp[k++] = a[left++];
            else
                tmp[k++] = a[right++];

        while(left <= leftEnd)    // Copy rest of first half
            tmp[k++] = a[left++];

        while(right <= rightEnd)  // Copy rest of right half
            tmp[k++] = a[right++];

        // Copy tmp back
        for(int i = 0; i < num; i++, rightEnd--)
            a[rightEnd] = tmp[rightEnd];
    }

X.
http://www.vogella.com/tutorials/JavaAlgorithmsMergesort/article.html
http://www.java2novice.com/java-sorting-algorithms/merge-sort/
        private int[] numbers;
        private int[] helper;

        private int number;

        public void sort(int[] values) {
                this.numbers = values;
                number = values.length;
                this.helper = new int[number];
                mergesort(0, number - 1);
        }

        private void mergesort(int low, int high) {
                // check if low is smaller then high, if not then the array is sorted
                if (low < high) {
                        // Get the index of the element which is in the middle
                        int middle = low + (high - low) / 2;
                        // Sort the left side of the array
                        mergesort(low, middle);
                        // Sort the right side of the array
                        mergesort(middle + 1, high);
                        // Combine them both
                        merge(low, middle, high);
                }
        }

        private void merge(int low, int middle, int high) {

                // Copy both parts into the helper array
                for (int i = low; i <= high; i++) {
                        helper[i] = numbers[i];
                }

                int i = low;
                int j = middle + 1;
                int k = low;
                // Copy the smallest values from either the left or the right side back
                // to the original array
                while (i <= middle && j <= high) {
                        if (helper[i] <= helper[j]) {
                                numbers[k] = helper[i];
                                i++;
                        } else {
                                numbers[k] = helper[j];
                                j++;
                        }
                        k++;
                }
                // Copy the rest of the left side of the array into the target array
                while (i <= middle) {
                        numbers[k] = helper[i];
                        k++;
                        i++;
                }

        }

X.
http://javahungry.blogspot.com/2013/06/java-sorting-program-code-merge-sort.html
    public static int[] mergeSort(int [] list) {
        if (list.length <= 1) {
            return list;
        }
        
        // Split the array in half
        int[] first = new int[list.length / 2];
        int[] second = new int[list.length - first.length];
        System.arraycopy(list, 0, first, 0, first.length);
        System.arraycopy(list, first.length, second, 0, second.length);
        
        // Sort each half
        mergeSort(first);
        mergeSort(second);
        
        // Merge the halves together, overwriting the original array
        merge(first, second, list);
        return list;
    }
    
    private static void merge(int[] first, int[] second, int [] result) {
        // Merge both halves into the result array
        // Next element to consider in the first array
        int iFirst = 0;
        // Next element to consider in the second array
        int iSecond = 0;
        
        // Next open position in the result
        int j = 0;
        // As long as neither iFirst nor iSecond is past the end, move the
        // smaller element into the result.
        while (iFirst < first.length && iSecond < second.length) {
            if (first[iFirst] < second[iSecond]) {
                result[j] = first[iFirst];
                iFirst++;
                } else {
                result[j] = second[iSecond];
                iSecond++;
            }
            j++;
        }
        // copy what's left
        System.arraycopy(first, iFirst, result, j, first.length - iFirst);
        System.arraycopy(second, iSecond, result, j, second.length - iSecond);
    }


It's stable.
http://www.vogella.com/tutorials/JavaAlgorithmsMergesort/article.html
public static void sort(Comparable[] a) {
        Comparable[] aux = new Comparable[a.length];
        sort(a, aux, 0, a.length-1);
        assert isSorted(a);
}

http://www.sinbadsoft.com/blog/sorting-big-files-using-k-way-merge-sort/
It consists of two steps: first, split the file into small chunks that would fit in memory, load each chunk, sort it, and write it back on disk. Second, perform a k-way merge on all the sorted chunks to get the final result.

External Merge Sort
https://code.google.com/p/externalsortinginjava/source/browse/trunk/src/main/java/com/google/code/externalsorting/ExternalSort.java
http://exceptional-code.blogspot.com/2011/07/external-sorting-for-sorting-large.html
1. Start reading the input file from the beginning.
2. Read M (or less if number of entries remaining in the file is less than M) numbers from the file and store it into a temp buffer.
3. Sort (using any good sorting method - Quicksort, for example) the numbers in the buffer stored in step 2.
4. Create a temp file in disk and write out the sorted numbers from step 3 to this temp file. Save the name of the temp file.
5. Repeat step 2 to 4 until all numbers from the input file has been read, sorted, and written out to temp files.
6. Open all the temp files (and set the read pointer to the beginning of the files).
7. Find the minimum number from the set of numbers currently pointed to by the file read pointer.
8. Write the number to disk. (To increase efficiency you could write the number to a buffer first and then flush the buffer out to disk when the buffer is full. But modern I/O libraries should be doing this anyway for you).
9. Read another number from the file that contained the minimum number at step 7.
10. Repeat step 7 to 9 until all numbers from all the temp files have been processed, merged, and written out to disk

Mergesort using Fork/Join Framework
http://www.java-allandsundry.com/2012/08/mergesort-using-forkjoin-framework.html
http://www.oracle.com/technetwork/articles/java/fork-join-422606.html
https://github.com/cowtowncoder/java-merge-sort





http://www.geeksforgeeks.org/3-way-merge-sort/
    public static void mergeSort3Way(Integer[] gArray)
    {
        // if array of size is zero returns null
        if (gArray == null)
            return;
        // creating duplicate of given array
        Integer[] fArray = new Integer[gArray.length];
        // copying alements of given array into
        // duplicate array
        for (int i = 0; i < fArray.length; i++)
            fArray[i] = gArray[i];
        // sort function
        mergeSort3WayRec(fArray, 0, gArray.length, gArray);
        // copy back elements of duplicate array
        // to given array
        for (int i = 0; i < fArray.length; i++)
            gArray[i] = fArray[i];
    }
    /* Performing the merge sort algorithm on the
       given array of values in the rangeof indices
       [low, high).  low is minimum index, high is
       maximum index (exclusive) */
    public static void mergeSort3WayRec(Integer[] gArray,
                  int low, int high, Integer[] destArray)
    {
        // If array size is 1 then do nothing
        if (high - low < 2)
            return;
        // Splitting array into 3 parts
        int mid1 = low + ((high - low) / 3);
        int mid2 = low + 2 * ((high - low) / 3) + 1;
        // Sorting 3 arrays recursively
        mergeSort3WayRec(destArray, low, mid1, gArray);
        mergeSort3WayRec(destArray, mid1, mid2, gArray);
        mergeSort3WayRec(destArray, mid2, high, gArray);
        // Merging the sorted arrays
        merge(destArray, low, mid1, mid2, high, gArray);
    }
    /* Merge the sorted ranges [low, mid1), [mid1,
       mid2) and [mid2, high) mid1 is first midpoint
       index in overall range to merge mid2 is second
       midpoint index in overall range to merge*/
    public static void merge(Integer[] gArray, int low,
                           int mid1, int mid2, int high,
                                   Integer[] destArray)
    {
        int i = low, j = mid1, k = mid2, l = low;
        // choose smaller of the smallest in the three ranges
        while ((i < mid1) && (j < mid2) && (k < high))
        {
            if (gArray[i].compareTo(gArray[j]) < 0)
            {
                if (gArray[i].compareTo(gArray[k]) < 0)
                    destArray[l++] = gArray[i++];
                else
                    destArray[l++] = gArray[k++];
            }
            else
            {
                if (gArray[j].compareTo(gArray[k]) < 0)
                    destArray[l++] = gArray[j++];
                else
                    destArray[l++] = gArray[k++];
            }
        }
        // case where first and second ranges have
        // remaining values
        while ((i < mid1) && (j < mid2))
        {
            if (gArray[i].compareTo(gArray[j]) < 0)
                destArray[l++] = gArray[i++];
            else
                destArray[l++] = gArray[j++];
        }
        // case where second and third ranges have
        // remaining values
        while ((j < mid2) && (k < high))
        {
            if (gArray[j].compareTo(gArray[k]) < 0)
                destArray[l++] = gArray[j++];
            else
                destArray[l++] = gArray[k++];
        }
        // case where first and third ranges have
        // remaining values
        while ((i < mid1) && (k < high))
        {
            if (gArray[i].compareTo(gArray[k]) < 0)
                destArray[l++] = gArray[i++];
            else
                destArray[l++] = gArray[k++];
        }
        // copy remaining values from the first range
        while (i < mid1)
            destArray[l++] = gArray[i++];
        // copy remaining values from the second range
        while (j < mid2)
            destArray[l++] = gArray[j++];
        // copy remaining values from the third range
        while (k < high)
            destArray[l++] = gArray[k++];
    }

Time Complexity: In case of 2-way Merge sort we get the equation: T(n) = 2T(n/2) + O(n)
Similarly, in case of 3-way Merge sort we get the equation: T(n) = 3T(n/3) + O(n)
By solving it using Master method, we get its complexity as O(n log 3n).. Although time complexity looks less compared to 2 way merge sort, the time taken actually may become higher because number of comparisons in merge function go higher
http://www.geeksforgeeks.org/binary-search-preferred-ternary-search/
int ternarySearch(int arr[], int l, int r, int x)
{
   if (r >= l)
   {
        int mid1 = l + (r - l)/3;
        int mid2 = mid1 + (r - l)/3;
        // If x is present at the mid1
        if (arr[mid1] == x)  return mid1;
        // If x is present at the mid2
        if (arr[mid2] == x)  return mid2;
        // If x is present in left one-third
        if (arr[mid1] > x) return ternarySearch(arr, l, mid1-1, x);
        // If x is present in right one-third
        if (arr[mid2] < x) return ternarySearch(arr, mid2+1, r, x);
        // If x is present in middle one-third
        return ternarySearch(arr, mid1+1, mid2-1, x);
   }
   // We reach here when element is not present in array
   return -1;
}

Which of the above two does less comparisons in worst case?
From the first look, it seems the ternary search does less number of comparisons as it makes Log3n recursive calls, but binary search makes Log2n recursive calls. Let us take a closer look.
The following is recursive formula for counting comparisons in worst case of Binary Search.
   T(n) = T(n/2) + 2,  T(1) = 1
The following is recursive formula for counting comparisons in worst case of Ternary Search.
   T(n) = T(n/3) + 4, T(1) = 1
In binary search, there are 2Log2n + 1 comparisons in worst case. In ternary search, there are 4Log3n + 1 comparisons in worst case.
Time Complexity for Binary search = 2clog2n + O(1)
Time Complexity for Ternary search = 4clog3n + O(1)
Therefore, the comparison of Ternary and Binary Searches boils down the comparison of expressions 2Log3n and Log2n . The value of 2Log3n can be written as (2 / Log23) * Log2n . Since the value of (2 / Log23) is more than one, Ternary Search does more comparisons than Binary Search in worst case.
https://www.quora.com/Algorithms-How-does-merge-sort-have-space-complexity-O-n-for-worst-case


Mergesort, if implemented to create arrays in the recursive calls, will create many of them, but they won't coexist at the same time. In every recursive call you create an array (or 2 depending on an implementation) for merging and they take no more than O(n) space, and then when the merging is done, these arrays are deleted and some new ones will be created after a moment in some other recursive call. If you counted how much space all the arrays that ever have been created took, it'd be O(n log n), but you don't need to care about this information - you don't need more than O(n) space, because when you need to create an array, all the other ones don't longer exist and don't occupy any memory. Note that you can simply declare 2 - or 3 - arrays in the beginning, each the length of n, and then store the sequence in one of them, while using the other for merging, it will improve the performance as well as show you beyond doubt there's no need for more than O(n) of memory.

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts