Sorted squares of numbers in a list in O(n)? - algorithm

Given a list of integers in sorted order, say, [-9, -2, 0, 2, 3], we have to square each element and return the result in a sorted order. So, the output would be: [0, 4, 4, 9, 81].
I could figure out two approaches:
O(NlogN) approach - We insert the square of each element in a hashset. Then copy the elements into a list, sort it and then return it.
O(n) approach - If there is a bound for the input elements (say -100 to -100), then we create a boolean list of size 20000 (to store -10000 to 10000). For each of the input elements, we mark the corresponding square number as true. For e.g., for 9 in the input, I will mark 81 in the boolean array as true. Then traverse this boolean list and insert all the true elements into a return list. Note that in this we make an assumption - that there is a bound for the input elements.
Is there some way in which we could do it in O(n) time even without assuming any bounds for the input?

Well I can think of an O(n) approach
Split the input into 2 lists. One with negative numbers, let's call this list A. And one with positive numbers and 0, list B. This is done while preserving the input order, which is trivial : O(n)
Reverse list A. We do this because once squared, the greater than relation between the elements if flipped
Square every item of both list in place : O(n)
Run a merge operation not unlike that of a merge sort. : O(n)
Total: O(n)
Done :)

Is there some way in which we could do it in O(n) time even without assuming any bounds for the input?
Absolutely.
Since the original list is already sorted you are in luck!
given two numbers x and y
if |x| > |y| then x^2 > y^2
So all you have to do is to split the list into two parts, one for all the negative numbers and the other one for all the positive ones
Reverse the negative one and make them positive
Then you merge those two lists into one using insertion. This runs in O(n) since both lists are sorted.
From there you can just calculate the square and put them into the new list.

We can achieve it by 2 pointer technique. 1 pointer at the start and other at the end. Compare the squares and move the pointers accordingly and start allocating the max element at the end of the new list.
Time = O(n)
Space = O(n)
Can you do it inplace ? To reduce space complexity.

This can be done with O(n) time and space. We need two pointers. The following is the Java code:
public int[] sortedSquares(int[] A) {
int i = 0;
int j = A.length - 1;
int[] result = new int[A.length];
int count = A.length - 1;
while(count >= 0) {
if(Math.abs(A[i]) > Math.abs(A[j])) {
result[count] = A[i]*A[i];
i++;
}
else {
result[count] = A[j]*A[j];
j--;
}
count--;
}
return result;
}
Start from the end ad compare the absolute values. And then create the answer.

class Solution {
public int[] sortedSquares(int[] nums) {
int left = 0;
int right = nums.length -1;
int index = nums.length- 1;
int result[] = new int [nums.length];
while(left<=right)
{
if(Math.abs(nums[left])>Math.abs(nums[right]))
{
result[index] = nums[left] * nums[left];
left++;
}
else
{
result[index] = nums[right] * nums[right];
right--;
}
index--;
}
return result;
}
}
By using the naive approach this question will be very easy but it will require O(nlogn) complexity
To solve this question in O(n), two pointer method is the best approach.
Create a new result array with the same length as the given array, and store it pointer as array length
Assign a pointer at the start of the array and then assign another pointer at the last of the array, as we know the last element from either side will be highest
[-9, -2, 0, 2, 3]
compare -9 and 3 absolute value
if the left value then store the value to the resultant array and decrease its index value and increase the left, otherwise decrease the right.

Python3 solution. time complexity - O(N) and space complexity O(1).
def sorted_squArrres(Arr:list) ->list:
i = 0
j = len(Arr)-1
while i<len(Arr):
if Arr[i]*Arr[i]<Arr[j]*Arr[j]:
Arr.insert(0,Arr[j]*Arr[j])
Arr.pop(j+1)
i+=1
continue
if Arr[i]*Arr[i]>Arr[j]*Arr[j]:
Arr.insert(0,Arr[i]*Arr[i])
Arr.pop(i+1)
i+=1
continue
else:
if i!=j:
Arr.insert(0,Arr[j]*Arr[j])
Arr.insert(0,Arr[j+1]*Arr[j+1])
Arr.pop(j+2)
Arr.pop(i+2)
i+=2
else:
Arr.insert(0,Arr[j]*Arr[j])
Arr.pop(j+1)
i+=1
return Arr
X = [[-4,-3,-2,0,3,5,6],[1,2,3,4,5],[-5,-4,-3,-2,-1],[-9,-2,0,2,3]]
for i in X:
# looping differnt kinds of inputs
print(sorted_squArrres(i))
# outputs
'''
[0, 4, 9, 9, 16, 25, 36]
[1, 4, 9, 16, 25]
[1, 4, 9, 16, 25]
[0, 4, 4, 9, 81]
'''

Related

Iterative algorithm for N choose K, without repetitions, order matters

I'm looking for an iterative algorithm to obtain all of the permutations of K elements extracted from a set of N elements, without repetitions (i.e., without substitutions), and for which order matters.
I know the amount of permutations has to be N!/(N-K)!.
Have you any ideas?
Thank you.
Ivan
Approach 1:
Simpler Idea:
Since the order matters, we will try to utilize next_permutation algorithm. The next_permutation function gives next lexicographically unique permutation.
Algorithm:
Create a new array A of size equals to size of original array.
Assign last k numbers 1,2,3,..k such that k ends last. Assign remaining numbers as 0.
Now while iterating through permutations using next_permutation, select only indices in original array where value in A > 0, maintaning order.
Explanation for correctness:
Since in newly created array there are N numbers of which N-k are repeated, total unique permutations become N!/(N-k)! which gives us our desired outcome.
Example:
Input: X = [1,2,3], k=2
Now, we create A = [0,1,2].
All permutations:
[0, 1, 2],
[0, 2, 1],
[1, 0, 2],
[1, 2, 0],
[2, 0, 1],
[2, 1, 0].
Choose only indices i of these permutations from original array where A[i] > 0, which will yield,
[2,3],
[3,2],
[1,3],
[1,2],
[3,1],
[2,1].
If you want above in sorted order, use negative numbers and initialize first k numbers with -k,-k-1,..-1 and remaining with 0 and apply the algorithm with slight modification, by selecting index i in original array, such that A[i] < 0 while maintaining order.
Sidenote:
If order doesn't matter, initialize A with k -1s in the beginning and remaining 0 and use the iterative permutations algorithm which will generate unique possible k selections from N items.
Approach 2:(better than Approach 1)
Algorithm:
Start by selecting first K numbers and populate in array A, it will store the index of chosen elements from original array. We mark it as the first selection.
Now get all remaining permutations in lexicographical order.
How to get next combination considering order? We will permute the selection if possible, otherwise return lexicographically greater selection.
Idea for getting next selection in lexicograhic order if permutations are exhausted:
We consider our current combination, and find the rightmost element
that has not yet reached its highest possible value. Once finding this
element, we increment it by 1, and assign the lowest valid value to
all subsequent elements.
from: https://cp-algorithms.com/combinatorics/generating_combinations.html
Example:
Input: X = [1,2,3,4], k=3
Now, we create A = [0,1,2].
All permutations:
[0,1,2] // initialization
[0,2,1] // next permutation
... // all permutations of [0,1,2]
...
[2,1,0] // reached last permutation of current selection
[0,1,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,1,0] // reached last permutation of current selection
[0,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,0] // reached last permutation of current selection
[1,2,3] // get next selection in lexicographic order as permutations are exhausted
...
[3,2,1] // reached last permutation of current selection
Code (0-based indexing, so start with 0-k-1 initialization):
bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
int k = (int)a.size();
if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
// if `a` was already in descending order,
// next_permutation returned false and changed the array to sorted order.
// now find next combination if possible
for (int i = k - 1; i >= 0; i--) {
if (a[i] < n - k + i + 1) {
a[i]++;
for (int j = i + 1; j < k; j++)
a[j] = a[j - 1] + 1;
return true;
}
}
return false;
}
References:
Next permutations:
https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order
std::next_permutation Implementation Explanation
Next combination without order:
https://cp-algorithms.com/combinatorics/generating_combinations.html

Find the 1 non-repeating element in a given array without XOR or Map in O(n)

How can I find the one non repeating element in an array that all other elements appear exactly twice, when I'm not allowed to use a hash map or the operator XOR?
In O(n) time complexity
Examples:
Input
arr[] = {14, 1, 14, 4, 12, 2, 1, 2, 3, 3}
Output
4
If you want to do it in java Script then inside a for loop you can check if the first index and the last index of that item are same then return that item else return -1.
function getFirstDistinctNumber() {
arr = [14, 1, 14, 4, 12, 2, 1, 2, 3, 3];
for (let i=0; i<arr.length; i++) {
if(arr.indexOf(arr[i]) == arr.lastIndexOf(arr[i])) {
return arr[i];
}
}
return -1;
}
console.log(getFirstDistinctNumber());
And also in java, you can do the same but lastIndexOf() is not present for array. so you can do it by creating an array list
import java.util.*;
class FindDistinct {
public static void main(String[] args) {
// create an empty array list with an initial capacity
ArrayList<Integer> inputList = new ArrayList<Integer>();
// use add() method to add values in the list
inputList.add(14);
inputList.add(1);
inputList.add(14);
inputList.add(4);
inputList.add(12);
inputList.add(2);
inputList.add(1);
inputList.add(2);
inputList.add(3);
inputList.add(3);
for(int i=0; i< inputList.size(); i++) {
if(inputList.indexOf(inputList.get(i)) == inputList.lastIndexOf(inputList.get(i))) {
System.out.println(inputList.get(i));
break;
}
}
}
}
sorting the array and then using stack, you can find the required element
# code is in python
arr = [14, 1, 14, 4, 12, 2, 1, 2, 3, 3,12]
# sort the array
arr = sorted(arr)
# use a stack to find out the required element
stack = []
for ele in arr:
if len(stack) == 0:
stack.append(ele)
elif stack[-1]==ele:
stack.pop()
else:
stack.append(ele)
print(stack[-1]) # item with one occuerence
# output : 4
There's a way compute that in O(1) space and O(n log n) time. Simply binary search the value. For a given number x count the number of elements that less or equal to x - if this value is odd then the number you're looking for is less or equal to x, otherwise if it's even, then it's greater.
(technically the running time is O(n log k) where k is max_value - min_value from the elements in the array, but there's a way to modify it to work in O(n log n) if needed.)
I found the answer to the problem, using this video: https://www.youtube.com/watch?v=aZneq1PWFkg
You can get the median in O(n) time, then you can sort all of the numbers which are greater or equal to the median to the right of it and the ones that are less than it, to be on the left in O(n) time. now everything is sorted in a way that everything that's bigger than the median is on the left and bigger is on the right.
Then You search the array once more to see if the median has a twin, if it doesn’t, you’re done that’s your lonely number, if you’ve found the twin on the left side and the index of the median is odd then you take everything that’s on the left side of the median including it (and throw the others away), same for if you’ve found it in the right side. If the medians index is even you take the opposite side that you find the twin on without including the median. You keep doing the same algo from beginning until you’ve found it.
Then you can get T(n) = T(n/2) + Θ(n)
And with masters theorem you get Θ(n).
In c++ using O(n) compexity.
int arrayUnique(int *arr, int size)
{
int count;
for(int i=0;i<size;i++)
{
count=0;
for(int j=0;j<size;j++)
{
if(i==j){
continue;
}
if(arr[i] == arr[j]){
count=1;
}
}
if(count==0){
return arr[i];
}
}
}

time omplexity of finding two indices of same element in an array

I am trying to design an algorithm to find indices of two same element in an array. The input is an array and the output is two indices i & j such that array[i]=array[j].
time complexity must be O(nlogn).
here is what I tried
let i=0 to size_of_array{
let j=i+1 to size_of_array{
if array[j]=array[i]{
print(i, j)
}
}
}
Nested loop is O(n^2), but if I try to design like this. what the time complexity would be?
n is the size of array
my implementation would run O(n[(n-1)+(n-2)+(n-3)....+1]) times. Does it still O(n^2),Someone told me it is O(nlogn), why?
You can keep two array: one with the values (A) and one with the indices (I). A possible O(nlogn) algorithm could be:
Sort values array A in parallel with index array I. (Time complexity: O(nlogn)).
Scan A and compare every elements with its right neighbor, if a duplicate is found you can return the corresponding index in I. (Time complexity: O(n))
I implemented this idea in a python function:
import operator
def repeatedNumber(A):
if len(A) <= 1:
return -1
# building the indices array
indices = range(len(A))
# join the two arrays
zipped = zip(A, indices)
# sort the arrays based on value
zipped = sorted(zipped, key=operator.itemgetter(0))
# scan the array and compare every pair of neighbor
for i in range(len(zipped)):
if zipped[i][0] == zipped[i + 1][0]:
return zipped[i][1], zipped[i+1][1]
return -1
You can try with some examples:
For A = [2,3,5,2,6] give (0, 3)
For A = [2, 3, 100, 6, 15, 40, 7, 3] give (1, 7)
As you know the time complexity of your algorithm is O(n^2). To get a better result you can sort the array first and then find the indices.
If you sort the array, two indices with the same value could be located beside each other. Hence, you can iterate over the sorted array, and report their original index of the two current neighbor indices in the sorted array.
The time complexity of sorting could be O(n log n) and then iterating over the array is O(n). Hence, this algorithm is O(n log n).
You could use a map for inverse lookup
function findSame(theValues) {
var inverseLookup = {};
var theLength = theValues.length;
for (var i = 0; i < theLength; ++i) {
if (inverseLookup[theValues[i]] != undefined) {
return ([inverseLookup[theValues[i]], i]);
}
inverseLookup[theValues[i]] = i;
}
return [];
}
console.log(findSame([1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9]));
for loop has O(n) time + inverseLookup has O(1) time + O(n) space (hash table)

Longest subarray whose elements form a continuous sequence

Given an unsorted array of positive integers, find the length of the longest subarray whose elements when sorted are continuous. Can you think of an O(n) solution?
Example:
{10, 5, 3, 1, 4, 2, 8, 7}, answer is 5.
{4, 5, 1, 5, 7, 6, 8, 4, 1}, answer is 5.
For the first example, the subarray {5, 3, 1, 4, 2} when sorted can form a continuous sequence 1,2,3,4,5, which are the longest.
For the second example, the subarray {5, 7, 6, 8, 4} is the result subarray.
I can think of a method which for each subarray, check if (maximum - minimum + 1) equals the length of that subarray, if true, then it is a continuous subarray. Take the longest of all. But it is O(n^2) and can not deal with duplicates.
Can someone gives a better method?
Algorithm to solve original problem in O(n) without duplicates. Maybe, it helps someone to develop O(n) solution that deals with duplicates.
Input: [a1, a2, a3, ...]
Map original array as pair where 1st element is a value, and 2nd is index of array.
Array: [[a1, i1], [a2, i2], [a3, i3], ...]
Sort this array of pairs with some O(n) algorithm (e.g Counting Sort) for integer sorting by value.
We get some another array:
Array: [[a3, i3], [a2, i2], [a1, i1], ...]
where a3, a2, a1, ... are in sorted order.
Run loop through sorted array of pairs
In linear time we can detect consecutive groups of numbers a3, a2, a1. Consecutive group definition is next value = prev value + 1.
During that scan keep current group size (n), minimum value of index (min), and current sum of indices (actualSum).
On each step inside consecutive group we can estimate sum of indices, because they create arithmetic progression with first element min, step 1, and size of group seen so far n.
This sum estimate can be done in O(1) time using formula for arithmetic progression:
estimate sum = (a1 + an) * n / 2;
estimate sum = (min + min + (n - 1)) * n / 2;
estimate sum = min * n + n * (n - 1) / 2;
If on some loop step inside consecutive group estimate sum equals to actual sum, then seen so far consecutive group satisfy the conditions. Save n as current maximum result, or choose maximum between current maximum and n.
If on value elements we stop seeing consecutive group, then reset all values and do the same.
Code example: https://gist.github.com/mishadoff/5371821
See the array S in it's mathematical set definition :
S = Uj=0k (Ij)
Where the Ij are disjoint integer segments. You can design a specific interval tree (based on a Red-Black tree or a self-balancing tree that you like :) ) to store the array in this mathematical definitions. The node and tree structures should look like these :
struct node {
int d, u;
int count;
struct node *n_left, *n_right;
}
Here, d is the lesser bound of the integer segment and u, the upper bound. count is added to take care of possible duplicates in the array : when trying to insert an already existing element in the tree, instead of doing nothing, we will increment the count value of the node in which it is found.
struct root {
struct node *root;
}
The tree will only store disjoint nodes, thus, the insertion is a bit more complex than a classical Red-Black tree insertion. When inserting intervals, you must scans for potential overflows with already existing intervals. In your case, since you will only insert singletons this should not add too much overhead.
Given three nodes P, L and R, L being the left child of P and R the right child of P. Then, you must enforce L.u < P.d and P.u < R.d (and for each node, d <= u, of course).
When inserting an integer segment [x,y], you must find "overlapping" segments, that is to say, intervals [u,d] that satisfies one of the following inequalities :
y >= d - 1
OR
x <= u + 1
If the inserted interval is a singleton x, then you can only find up to 2 overlapping interval nodes N1 and N2 such that N1.d == x + 1 and N2.u == x - 1. Then you have to merge the two intervals and update count, which leaves you with N3 such that N3.d = N2.d, N3.u = N1.u and N3.count = N1.count + N2.count + 1. Since the delta between N1.d and N2.u is the minimal delta for two segments to be disjoint, then you must have one of the following :
N1 is the right child of N2
N2 is the left child of N1
So the insertion will still be in O(log(n)) in the worst case.
From here, I can't figure out how to handle the order in the initial sequence but here is a result that might be interesting : if the input array defines a perfect integer segment, then the tree only has one node.
UPD2: The following solution is for a problem when it is not required that subarray is contiguous. I misunderstood the problem statement. Not deleting this, as somebody may have an idea based on mine that will work for the actual problem.
Here's what I've come up with:
Create an instance of a dictionary (which is implemented as hash table, giving O(1) in normal situations). Keys are integers, values are hash sets of integers (also O(1)) – var D = new Dictionary<int, HashSet<int>>.
Iterate through the array A and for each integer n with index i do:
Check whether keys n-1 and n+1 are contained in D.
if neither key exists, do D.Add(n, new HashSet<int>)
if only one of the keys exists, e.g. n-1, do D.Add(n, D[n-1])
if both keys exist, do D[n-1].UnionWith(D[n+1]); D[n+1] = D[n] = D[n-1];
D[n].Add(n)
Now go through each key in D and find the hash set with the greatest length (finding length is O(1)). The greatest length will be the answer.
To my understanding, the worst case complexity will be O(n*log(n)), only because of the UnionWith operation. I don't know how to calculate the average complexity, but it should be close to O(n). Please correct me if I am wrong.
UPD: To speak code, here's a test implementation in C# that gives the correct result in both of the OP's examples:
var A = new int[] {4, 5, 1, 5, 7, 6, 8, 4, 1};
var D = new Dictionary<int, HashSet<int>>();
foreach(int n in A)
{
if(D.ContainsKey(n-1) && D.ContainsKey(n+1))
{
D[n-1].UnionWith(D[n+1]);
D[n+1] = D[n] = D[n-1];
}
else if(D.ContainsKey(n-1))
{
D[n] = D[n-1];
}
else if(D.ContainsKey(n+1))
{
D[n] = D[n+1];
}
else if(!D.ContainsKey(n))
{
D.Add(n, new HashSet<int>());
}
D[n].Add(n);
}
int result = int.MinValue;
foreach(HashSet<int> H in D.Values)
{
if(H.Count > result)
{
result = H.Count;
}
}
Console.WriteLine(result);
This will require two passes over the data. First create a hash map, mapping ints to bools. I updated my algorithm to not use map, from the STL, which I'm positive uses sorting internally. This algorithm uses hashing, and can be easily updated for any maximum or minimum combination, even potentially all possible values an integer can obtain.
#include <iostream>
using namespace std;
const int MINIMUM = 0;
const int MAXIMUM = 100;
const unsigned int ARRAY_SIZE = MAXIMUM - MINIMUM;
int main() {
bool* hashOfIntegers = new bool[ARRAY_SIZE];
//const int someArrayOfIntegers[] = {10, 9, 8, 6, 5, 3, 1, 4, 2, 8, 7};
//const int someArrayOfIntegers[] = {10, 6, 5, 3, 1, 4, 2, 8, 7};
const int someArrayOfIntegers[] = {-2, -3, 8, 6, 12, 14, 4, 0, 16, 18, 20};
const int SIZE_OF_ARRAY = 11;
//Initialize hashOfIntegers values to false, probably unnecessary but good practice.
for(unsigned int i = 0; i < ARRAY_SIZE; i++) {
hashOfIntegers[i] = false;
}
//Chage appropriate values to true.
for(int i = 0; i < SIZE_OF_ARRAY; i++) {
//We subtract the MINIMUM value to normalize the MINIMUM value to a zero index for negative numbers.
hashOfIntegers[someArrayOfIntegers[i] - MINIMUM] = true;
}
int sequence = 0;
int maxSequence = 0;
//Find the maximum sequence in the values
for(unsigned int i = 0; i < ARRAY_SIZE; i++) {
if(hashOfIntegers[i]) sequence++;
else sequence = 0;
if(sequence > maxSequence) maxSequence = sequence;
}
cout << "MAX SEQUENCE: " << maxSequence << endl;
return 0;
}
The basic idea is to use the hash map as a bucket sort, so that you only have to do two passes over the data. This algorithm is O(2n), which in turn is O(n)
Don't get your hopes up, this is only a partial answer.
I'm quite confident that the problem is not solvable in O(n). Unfortunately, I can't prove it.
If there is a way to solve it in less than O(n^2), I'd suspect that the solution is based on the following strategy:
Decide in O(n) (or maybe O(n log n)) whether there exists a continuous subarray as you describe it with at least i elements. Lets call this predicate E(i).
Use bisection to find the maximum i for which E(i) holds.
The total running time of this algorithm would then be O(n log n) (or O(n log^2 n)).
This is the only way I could come up with to reduce the problem to another problem that at least has the potential of being simpler than the original formulation. However, I couldn't find a way to compute E(i) in less than O(n^2), so I may be completely off...
here's another way to think of your problem: suppose you have an array composed only of 1s and 0s, you want to find the longest consecutive run of 1s. this can be done in linear time by run-length encoding the 1s (ignore the 0's). in order to transform your original problem into this new run length encoding problem, you compute a new array b[i] = (a[i] < a[i+1]). this doesn't have to be done explicitly, you can just do it implicitly to achieve an algorithm with constant memory requirement and linear complexity.
Here are 3 acceptable solutions:
The first is O(nlog(n)) in time and O(n) space, the second is O(n) in time and O(n) in space, and the third is O(n) in time and O(1) in space.
build a binary search tree then traverse it in order.
keep 2 pointers one for the start of max subset and one for the end.
keep the max_size value while iterating the tree.
it is a O(n*log(n)) time and space complexity.
you can always sort numbers set using counting sort in a linear time
and run through the array, which means O(n) time and space
complexity.
Assuming there isn't overflow or a big integer data type. Assuming the array is a mathematical set (no duplicate values). You can do it in O(1) of memory:
calculate the sum of the array and the product of the array
figure out what numbers you have in it assuming you have the min and max of the original set. Totally it is O(n) time complexity.

finding the sum of smaller elements on left

i came across a problem of finding the number of smaller elements on left of each element in an array of integers, which can be solved in O(nlgn) by using Binary Indexed trees(like AVL, etc) or Merge Sort. Using an AVL tree one can calculate the size of left sub-tree for each element and this would be the required answer. However I can't come up how to calculate the sum of the smaller elements left to each element efficiently. For each element , do i have to traverse the left sub-tree and sum the values at nodes or is there any better way(using Merge Sort etc)?
E.g for the array: 4,7,1,3,2 the required ans would be: 0,4,0,1,1
Thanks.
In Binary Indexed trees you store the number of child nodes for every node of the binary search tree. This allows you to find number of nodes, preceding each node (number of smaller elements).
For this task, you can store the sum of child node values for every node of the binary search tree. This allows you to find the sum of values for preceding nodes (sum of smaller elements). Also in O(n*log(n)).
Check this tutorial on Binary Indexed Tree. This is a structure, that uses O(n) memory and can proceed such tasks:
1. Change value of a[i] by(to) x, call this add(i,x);
2. Return sum all of a[i], i<=m, call this get(x).
in O(log n).
Now, how to use this to your task. You can do this in 2 steps.
Step one. Copy, sort and remove duplicates from original array. Now you can remap numbers, so they are in range [1...n].
Step 2. Now walk through the array from left to right. Let A[i] - be the value in original array, new[i] - mapped value. (if A = [2, 7, 11, -3, 7] then new = [2, 3, 4, 1, 2]).
The answer is get(new[i]-1).
Update the values: add(new[i], 1) for counting, add(new[i], A[i]) for sum.
All in all. Sorting and remapping is O(n logn). Working on array is n * O(log n) = O(n log n). So total complexity is O(n logn)
Alternatively, use treap (in russian).
EDIT: Building new array.
Suppose the original array A = [2, 7, 11,-3, 7]
Copy it to B and sort, B = [-3, 2, 7, 7, 11]
Do a unique B = [-3, 2, 7, 11].
Now to get new, you can
add all of elements to map in increasing order, e.g. (-3 -> 1, 2->2, 7->3, 11->4)
for each element in A, do a binary search over B
The following code has a complexity of O(nlogn).
It uses a binary indexed tree to solve the problem.
#include <cstdio>
using namespace std;
const int MX_RANGE = 100000, MX_SIZE = 100000;
int tree[MX_RANGE] = {0}, a[MX_SIZE];
int main() {
int n, mn = MX_RANGE, shift = 0;
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%d", &a[i]);
if(a[i] < mn) mn = a[i];
}
shift = 1-mn; // we need to remap all values to start from 1
for(int i = 0; i < n; i++) {
// Read answer
int sum = 0, idx = a[i]+shift-1;
while(idx>0) {
sum += tree[idx];
idx -= (idx&-idx);
}
printf("%d ", sum);
// Update tree
idx = a[i]+shift;
while(idx<=MX_RANGE) {
tree[idx] += a[i];
idx += (idx&-idx);
}
}
printf("\n");
}

Resources