I suggest you consider the following approach, but it only works if the array b has non-negative numbers. The algorithm works even if the input arrays (both a and b ) are not sorted.
Pseudo code
- Get the
max element of array b . - Create a new array
c size max + 1 and place 1 at position c[b[i]] . Create a new array d size max + 1 and fill it as follows:
d[0]=0;
d[i]=d[i-1] + c[i];
Create a new array e size n and fill it as follows:
if(a[i] > max) then e[i] = last(d)
otherwise e[i]=d[a[i]-1];
e array represents the solution: it contains in the i-th position the number counter of the array b below the i-th element of the array a . This example should be more explanatory than pseudo-code:
a = [5, 1, 4, 8, 17, 12, 22] b = [2, 4, 3, 4, 11, 13, 17] c = [0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1] d = [0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 5, 5, 6] e = [3, 0, 2, 3, 5, 4, 6]
Complexity
Steps 1, 2 and 4 are O(n). Step 3 is O(max(b))
if the input array b contains only "short" numbers (max (b) is in the same order of size n ), that the algorithm runs in O(n) . The algorithm can be optimized by creating an array of size max-min+1 and consider the counter 0 for all elements of the array a below min(b) .
Simple Java implementation:
int a[] = {5, 1, 4, 8, 17, 12, 22}; int b[] = {2, 4, 3, 4, 11, 13, 17}; int max = Arrays.stream(b).max().getAsInt(); int c[] = new int[max+1]; int d[] = new int[max+1]; int e[] = new int[a.length]; for(int i=0;i<b.length;i++){ c[b[i]]=1; } for(int i=1;i<c.length;i++){ d[i] = d[i-1] + c[i]; } for (int i = 0; i<a.length;i++){ e[i]=(a[i]>max)?d[d.length-1]:d[a[i]-1]; } System.out.println(Arrays.toString(a)); System.out.println(Arrays.toString(b)); System.out.println(Arrays.toString(c)); System.out.println(Arrays.toString(d)); System.out.println(Arrays.toString(e));