Find first inversion for an element in an array - arrays

Given an Array A with indices 1 <= i <= n, find the very first j, i + 1 <= j <= n, such that A[j] > A[i]. To find the total number of inversions for any given element, we create a copy of A and mergesort that copy. Then for each i in A, we perform a binary search on the copy of A(call it B) to locate it's position and the number of inversion for that element is one less then it's position in the copy of A. I understand this, but i'm having trouble determining how to modify this approach to locate the minimum possible conversion.
Example: A = {8, 3, 34, 13, 1, 2, 21, 5}
After copy and merge: B = {1, 2, 3, 5, 8, 13, 21, 34}
indices: {5, 6, 2, 8, 1, 4, 7, 3}
We see A[1] = 8, do a binary search on Array B, we find 8 at position 5, the algorithm should return 34 (index 3). If no inversion exists, return -1.
Complexity should be O(nlogn), i've sat through this problem for a few hours and can't think of a solution, all I could think of is finding the number of inversion but not the index j. Any help would be appreciated.

Related

Finding the number of unique positions occupied by every node after sequence of swaps

You have N (N <= 50000) nodes on a line, with node i in position i on the line. You are given a sequence of M different swaps (M <= 20000), that is written in the from (a1, b1) (a2, b2) …. (aM, bM). In every unit of time i = 1…M, the nodes at positions ai and bi swap. Then, the same M swaps happen again in minutes M + 1….2M, and then for 2M + 1…3M, and so on, continuing a cyclic fashion for K units of time (K < 10^18).
So for example,
At unit of time 1, nodes at positions a1 and b1 swap.
At unit of time 2, nodes at positions a2 and b2 swap.
…
At unit of time M, nodes at positions aM and bM swap.
At unit of time M + 1, nodes at positions a1 and b1 swap.
At unit of time M + 2, nodes at positions a2 and b2 swap.
And so on…
For every node, you are asked to determine the number of unique positions that it will occupy.
Example:
6 nodes, M = 4 (sequence consists of 4 swaps), and K = 7 (total units of time is 7).
Sequence:
(1, 2) (2, 3) (3, 4) (4, 5)
Simulation:
Time 0: {1, 2, 3, 4, 5, 6}
Time 1: {2, 1, 3, 4, 5, 6}
Time 2: {2, 3, 1, 4, 5, 6}
Time 3: {2, 3, 4, 1, 5, 6}
Time 4: {2, 3, 4, 5, 1, 6}
Time 5: {3, 2, 4, 5, 1, 6}
Time 6: {3, 4, 2, 5, 1, 6}
Time 7: {3, 4, 5, 2, 1, 6}
Answer:
Node 1 reaches positions {1, 2, 3, 4, 5}, so 5 positions.
Node 2 reaches positions {1, 2, 3, 4}, so 4 positions.
Node 3 reaches positions {1, 2, 3}, so 3 positions.
Node 4 reaches positions {2, 3, 4}, so 3 positions.
Node 5 reaches positions {3, 4, 5}, so 3 positions.
Node 6 doesn’t move, so it reaches position {6}, so 1 position.
One way of solving this could be by treating the nodes as a graph. Then, you could treat each of the swaps as connections, and then use a graph algorithm to calculate how you move between the nodes.
How can I successfully incorporate a graph algorithm into this problem?
EDIT: I’ve spent a few more hours thinking about this problem, and wanted to incorporate Ehsan’s idea into the solution. To find the possible nodes that will be in each position, you can use a recursive function like the one Ehsan is proposing (F(F(...(F(original_order))). Then, you can do this for every step in K. However, this would be an NK solution, which my be too slow as the largest number of operations I can perform is 10^9. How can I optimize my current idea?
You doesn't need graph for this.
They key point is reducing k
Lemma: assume from original node list {n1,n2,n3,...,nN} after series of step {s1,s2,.....,st} you reach to new order of nodes like {n_i1,...,n_iN} and also you have a unique visited list for each node as {n1_v1,...,n1_vn1},...,{nN_v1,...,nN_vnN}
then if you perform the same series of steps again, you can find the new order list of nodes and also unique visited list in O(n) with help of previous step.
so it's kind of dynamic programing.
by this approach the complexity of your algorithm could be as O(n*log(k/m)+m)

Algorithm for array permutation

We have an integer array A[] of size N (1 ≤ N ≤ 10^4), which originally is a sorted array with entries 1...N. For any permutation P of size N, the array is shuffled so that i-th entry from the left before the shuffle is at the Ai-th position after the shuffle. You would keep repeating this shuffle until the array is sorted again.
For example, for A[] = {1, 2, 3, 4}, if P = {1, 2, 3, 4}, it would only take one move for the array to be sorted (the entries would move to their original positions). If P = {4, 3, 1, 2}, then it would take 4 moves for the array to be sorted again:
Move 0 | [1, 2, 3, 4]
Move 1 | [3, 4, 2, 1]
Move 2 | [2, 1, 4, 3]
Move 3 | [4, 3, 1, 2]
Move 4 | [1, 2, 3, 4]
The problem is to find the sum of all positive integers J for which you can generate a permutation that requires J moves to get the array sorted again.
Example:
For A[] = {1, 2, 3, 4}, you can generate permutations that require 1, 2, 3, and 4 steps:
Requires 1 move: P = {1, 2, 3, 4}
Requires 2 moves: P = {1, 3, 2, 4}
Requires 3 moves: P = {1, 4, 2, 3}
Requires 4 moves: P = {4, 3, 1, 2}
So you would output 1 + 2 + 3 + 4 = 10.
Some observations I have made is that you can always generate a permutation that requires J moves for (1 ≤ J < N). This is because in the permutation, you would simply shift by 1 all the entries in the range of size J. However, for permutations that requires J moves where J ≥ N, you would need another algorithm.
The brute-force solution would be checking every permutation, or N! permutations which definitely wouldn't fit in run time. I'm looking for an algorithm with run time at most O(N^2).
EDIT 1: A permutation that requires N moves will always be guaranteed as well, as you can create a permutation where every entry is misplaced, and not just swapped with another entry. The question becomes how to find permutations where J > N.
EDIT 2: #ljeabmreosn made the observation that there exists a permutation that takes J steps if and only if there are natural numbers a_1 + ... + a_k = N and LCM(a_1, ..., a_k) = J. So using that observation, the problem comes down to finding all partitions of the array, or partitions of the integer N. However, this won't be a quadratic algorithm - how can I find them efficiently?
Sum of distinct orders of degree-n permutations.
https://oeis.org/A060179
This is the number you are looking for, with a formula, and some maple code.
As often when trying to compute an integer sequence, compute the first few values (here 1, 1, 3, 6, 10, 21) and look for it in the great "On-line Encyclopedia of Integer Sequences".
Here is some python code inspired by it, I think it fits your complexity goals.
def primes_upto(limit):
is_prime = [False] * 2 + [True] * (limit - 1)
for n in range(int(limit**0.5 + 1.5)):
if is_prime[n]:
for i in range(n*n, limit+1, n):
is_prime[i] = False
return [i for i, prime in enumerate(is_prime) if prime]
def sum_of_distinct_order_of_Sn(N):
primes = primes_upto(N)
res = [1]*(N+1)
for p in primes:
for n in range(N,p-1,-1):
pj = p
while pj <= n:
res[n] += res[n-pj] * pj
pj *= p
return res[N]
on my machine:
>%time sum_of_distinct_order_of_Sn(10000)
CPU times: user 2.2 s, sys: 7.54 ms, total: 2.21 s
Wall time: 2.21 s
51341741532026057701809813988399192987996798390239678614311608467285998981748581403905219380703280665170264840434783302693471342230109536512960230

Efficient method of finding single unsorted element in array

Assume an array of length n, which is sorted. (values are arbitrary, can be negative, not only ints)
One element is out of place, for example
-1, 2, 3.0, 4, 5, 10, 6, 7, 8, 9, 11, 12, 13, 14
n can be large.
Is there a way better than o(n) to find that element?

Algorithm to find length of a minimal sub-array containing all the elements of an array/vector

Let's say we have an array {7, 3, 7, 3, 1, 3, 4, 1}.
What I need is an algorithm (preferably some C++ code sample) which will return length of a minimal sub-array which contains all of the array's elements.
In this case, it would be 5: {7, 3, 1, 3, 4} and this is the shortest sub-array of the original array which contains all of the array's elements, which are 1, 3, 4 and 7.
Also, one more example of the array {2, 1, 1, 3, 2, 1, 1, 3} and the algorithm should return 3 since the subarray we are looking for is {1, 3, 2} (indices 2-4 of the original array).
I found some similar question here: Find minimum length of sub-list containing all elements of a list
but it does not seem answered.
The function signature should be like:
int algorithm(std::vector<int> &arr){...}
Find last subarray in O(n) :
For example, for the array [1, 2, 3, 2, 2, 1, 1], get the counts of the items in a hash table/Map (or array for small range) : { 1: 3, 2: 3, 3: 1 }
To find the start index of the subarray, start from the first value in the array and check if it's count is more than 1. If it's count is more than 1, decrease it's count by one, and continue to next value until a value with count of 1. Repeat the same backwards to find the last index of the subarray :
1, 2, 3, 2, 2, 1, 1
^ ^
Find the rest of the subarrays in O(n) :
Now to check if that is the minimum subarray, check for subarrays before it. For that, search before the first index for the last index of the value 1 that is at the last index. If it is found, change the first index to it, and decrease the last index by one :
1, 2, 3, 2, 2, 1, 1
^ ^
Now to find the last index of the new subarray, search between the first and last index for the value 2 that is at the last index and change the last index to it :
1, 2, 3, 2, 2, 1, 1
^ ^
Repeat until the value at the last index can't be found between the first and last index :
1, 2, 3, 2, 2, 1, 1
^ ^
Now check if the count of the new subarray is less than that of the previous subarray and update the indexes of the current minimum subarray if needed.
The search for the rest of the subarrays has to be repeated until the value at the last index can't be found before the first index.

Find the length of the longest contiguous sub-array in a sorted array in which the difference between the end and start values is at most k

I have a sorted array, for example
[0, 0, 3, 6, 7, 8, 8, 8, 10, 11, 13]
Here, let's say k = 1 so the longest sub-array is [7, 8, 8, 8] with length = 4.
As another example, consider [0, 0, 0, 3, 6, 9, 12, 12, 12, 12] with k = 3. Here the longest sub-array is [9, 12, 12, 12, 12] with length = 5.
So far, I have used a binary search algorithm O(n log n) which iterates from index 0 .. n - 1 and tries to find the rightmost index that satisfies our condition.
Is there a linear time algorithm to do this?
Yes, there is a linear time algorithm. You can use two pointers technique. Here is a pseudo code:
R = 0
res = 0
for L = 0 .. N - 1:
while R < N and a[R] - a[L] <= k:
R += 1
res = max(res, R - L)
It has O(n) time complexity because L and R are strictly increasing and each of them can be incremented only n times.
Why is this algorithm correct? For a fixed L, R is the index of the first element of the array such that a[R] - a[L] > k. That's why R - 1 is the index of the last element that fits. The length of [L, R - 1] subarray is exactly R - L. The resulting subarray is obtained by iterating over all possible values of L, that is, all possibilities are checked. That's why it always finds correct answer.

Resources