Search code examples
algorithmlanguage-agnosticpseudocodeminimization

What is the best algo for this array minimization problem?


I have an array say 'A' of size n having some numbers {a1, a2, …, an} not necessarily distinct. I have to create another array B = {b1, b2, …, bn} which are distinct such that the value of sum|ai - bi| over all i's{i =1 to i =n} is minimized.

Basically I want to minimize sum of |ai - bi| over all i

What is the best algo for this?

I tried a greedy approach:

pseudocode:

for i = 0 to n-1{
 if(a[i] not in b){
  b[i] = a[i];}
 else{
  cnt = 1
  assigned = false
 do{
  if(a[i]-cnt not in b){
   b[i] = a[i]-cnt;
   assigned = true}
  elif(a[i]+cnt not in b){
   b[i] = a[i]+cnt;
   assigned = true}
  else
   cnt++
 }while(assigned==false)
}//else
}//for loop

NOte: 'n' is an input variable. the goal is to minimize sum of |ai - bi| over all i


Solution

  • I came up with a O(NlogN) solution. Its based on sorting the input-sequence and greedily expanding the available numbers around it.

    Code implementation in Python:

    
    def get_closest_distinct_tuple(X: list):
        X = sorted(X, reverse=True)
        hmap = {}
        used_set = set()
    
        Y = []
    
        for x in X:
            if x not in used_set:
                Y.append(x)
                hmap[x] = 1
                used_set.add(x)
            else:
                Y.append(x + hmap[x])
                used_set.add(x + hmap[x])
                hmap[x] = 1 - hmap[x] if hmap[x] < 0 else -hmap[x]
    
        dist = sum([abs(X[i]-Y[i]) for i in range(len(X))])
        return dist, Y
    
    
    print(get_closest_distinct_tuple([20, 1, 1, 1, 1, 1, 1]))
    

    Output:

    Dist: 9
    Y = [20, 1, 2, 0, 3, -1, 4]
    

    I couldnt really find a way to prove that this is the most optimal solution out there.