Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here is an algorithm which should give you <code>O(NlgN)</code>:</p> <ol> <li><p>Iterate over the list once and build a map of <code>key =&gt; indexList</code>. So for ever key (element in the array) you store a list of all the indices where that key is in the array. This will take <code>O(N)</code> (iterate over the list) + <code>N*O(1)</code> (appending N items to lists) steps. So this step is <code>O(N)</code>. The second step requires that these lists are sorted which they will be as we are iterating over the list from left to right so a newly inserted index in a list will always be larger than all the other ones which are already in there.</p></li> <li><p>Iterate over the list again and for each element search the index lists for all keys which are larger than the current element for the first index which is after the current index. This gives you the number of elements to the right of the current one which are larger than the current element. As the index lists are sorted you can do a binary search which will take <code>O(k * lgN)</code> steps with <code>k</code> being the number of keys larger then the current one. If the number of keys has an upper limit then this is a constant as far as big-O is concerned. The second step here is to search all smaller keys and find the first index in the list which is prior to the current one. This will give you the number of element to the left of the current one which are smaller. Same reasoning as above this is <code>O(k * lgN)</code></p></li> </ol> <p>So assuming the number of keys is limited this should give you <code>O(N) + N * 2 * O(lgN)</code> so overall <code>O(NlgN)</code> if I'm not mistaken.</p> <p><strong>Edit</strong>: Pseudo code:</p> <pre><code>int[] list; map&lt;int =&gt; int[]&gt; valueIndexMap; foreach (int i = 0; i &lt; list.length; ++i) { // N iterations int currentElement = list[i]; // O(1) int[] indexList = valueIndexMap[currentElement]; // O(1) indexList.Append(i); // O(1) } foreach (int i = 0; i &lt; list.length; ++i) { // N iterations int currentElement = list[i]; // O(1) int numElementsLargerToTheRight; int numElementsSmallerToTheLeft; foreach (int k = currentElement + 1; k &lt; maxKeys; ++k) { // k iterations with k being const int[] indexList = valueIndexMap[k]; // O(1) int firstIndexBiggerThanCurrent = indexList.BinaryFindFirstEntryLargerThan(i); // O(lgN) numElementsLargerToTheRight += indexList.Length - firstIndexBiggerThanCurrent; // O(1) } foreach (int k = currentElement - 1; k &gt;= 0; --k) { // k iterations with k being const int[] indexList = valueIndexMap[k]; // O(1) int lastIndexSmallerThanCurrent = indexList.BinaryFindLastEntrySmallerThan(i); // O(lgN) numElementsSmallerToTheLeft += lastIndexSmallerThanCurrent; // O(1) } } </code></pre> <p><strong>Update</strong>: I tinkered around <a href="http://ideone.com/ni51ah" rel="nofollow">with a C# implementation</a> in case anyone is interested;</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload