Open In App

Find the value of K after replacing every index of the array by |ai – K|

Last Updated : 23 Aug, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array, arr[] containing n integers, the task is to find an integer (say K) such that after replacing each and every index of the array by |ai  – K| where ( i ? [1, n]), results in a sorted array. If no such integer exists that satisfies the above condition then return -1.

Examples:

Input: arr[ ] = [10, 5, 4, 3, 2, 1]
Output: 8
Explanation: Upon performing the operation |ai-8|, we get [2, 3, 4, 5, 6, 7] which is sorted.

Input: arr[ ] = [1, 2, 3, 4, 5, 6] 
Output: 0
Explanation: Since the array is already sorted so the value of K would be 0 in this case.

Approach: The problem can be solved based on the following observation:

Observations:

For the array to be sorted each pair of adjacent elements should be sorted. That means few cases arise if we take care for particular ai and ai+1 and those are as follows:

  • Let (ai < ai+1 ), so the following inequality arise: 
    • If (K ?ai) then upon  (ai – K ? ai+1 – K) the elements will be as it is (ai < ai+1).
    • If (K ? ai) then upon  ( K – ai ? K – ai+1 ) the elements will be as it is (ai > ai+1).
    • So, K should be midway between ai and ai+1 that is K should be K ? (ai + ai+1)/2 .
  • Similarly for (ai > ai+1) the value of k would be K ? (ai + ai+1)/2 
  • Finally we will take the minimum of all for which (K < ai) and maximum of all for which (K > ai).

Follow the steps mentioned below to implement the idea:

  • Initialize two variables l and r for the two values of k explained above.
  • Iterate over the array and check if (ai < ai+1) then store in r the minimum of r so far and the present value of K.
  • Else if, (ai > ai+1) stores it in l the maximum of l so far and the present value of K.
  • Finally if (l > r) return -1;
  • Else, return l 

Below is the Implementation of the above approach: 

C++




// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
 
// Function to find K
void findk(int a[], int n)
{
 
    // Initializing the two variables
    int l = 0, r = 1e9;
 
    for (int i = 0; i < n - 1; i++) {
 
        // If (a[i] < a[i+1]) then take
        // minimum and store in variable
 
        if (a[i] < a[i + 1]) {
            r = min(r, (a[i] + a[i + 1]) / 2);
        }
 
        // If (a[i]>a[i+1]) then take
        // maximum and store in
        // separate variable
        else if (a[i] > a[i + 1]) {
            l = max(l, (a[i] + a[i + 1] + 1) / 2);
        }
    }
 
    if (l > r) {
        cout << "-1";
    }
 
    else
 
        cout << l << endl;
}
 
// Driver function
int main()
{
    int arr[] = { 10, 5, 4, 3, 2, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    findk(arr, n);
    return 0;
}


Java




// Java Implementation
 
import java.util.*;
 
class GFG {
    public static void main(String[] args)
    {
        int[] arr = { 10, 5, 4, 3, 2, 1 };
        int n = arr.length;
        find(arr, n);
    }
 
    public static void find(int[] arr, int n)
    {
        // Initializing the two variables
        int l = 0;
        int r = 1000000000;
        for (int i = 0; i < n - 1; i++) {
 
            // If (a[i]<a[i+1]) then take minimum and store in variable)
 
            if (arr[i] < arr[i + 1]) {
                r = Math.min(r, (arr[i] + arr[i + 1]) / 2);
            }
 
            // If (a[i]>a[i+1]) then take maximum and store in separate variable)
 
            else if (arr[i] > arr[i + 1]) {
                l = Math.max(l,
                             (arr[i] + arr[i + 1] + 1) / 2);
            }
        }
 
        if (l > r) {
            System.out.println(-1);
        }
        else {
            System.out.println(l);
        }
    }
}


Python3




# Python code for the above approach
 
# Function to find K
def findk(a, n):
 
    # Initializing the two variables
    l = 0
    r = 10**9
 
    for i in range(n - 1):
 
        # If (a[i] < a[i+1]) then take
        # minimum and store in variable
        if (a[i] < a[i + 1]):
            r = min(r, (a[i] + a[i + 1]) // 2)
 
        # If (a[i]>a[i+1]) then take
        # maximum and store in
        # separate variable
        elif (a[i] > a[i + 1]):
            l = max(l, (a[i] + a[i + 1] + 1) // 2)
 
    if (l > r):
        print("-1")
 
    else:
        print(l)
 
# Driver function
if __name__ == '__main__':
    arr = [10, 5, 4, 3, 2, 1]
    n = len(arr)
 
    # Function Call
    findk(arr, n)


C#




// C# code for the above approach:
using System;
public class GFG {
 
  static public void Main()
  {
 
    // Code
    int[] arr = { 10, 5, 4, 3, 2, 1 };
    int n = arr.Length;
    find(arr, n);
  }
 
  static void find(int[] arr, int n)
  {
     
    // Initializing the two variables
    int l = 0;
    int r = 1000000000;
    for (int i = 0; i < n - 1; i++)
    {
       
      // If (a[i]<a[i+1]) then take minimum and store
      // in variable)
      if (arr[i] < arr[i + 1]) {
        r = Math.Min(r, (arr[i] + arr[i + 1]) / 2);
      }
 
      // If (a[i]>a[i+1]) then take maximum and store
      // in separate variable)
      else if (arr[i] > arr[i + 1]) {
        l = Math.Max(l,
                     (arr[i] + arr[i + 1] + 1) / 2);
      }
    }
 
    if (l > r) {
      Console.WriteLine(-1);
    }
    else {
      Console.WriteLine(l);
    }
  }
}
 
// This code is contributed by karthik


Javascript




// JavaScript code for the above approach:
 
// Function to find K
function findk(a, n) {
     
    // Initializing the two variables
    let l = 0, r = 1e9;
 
    for (let i = 0; i < n - 1; i++) {
         
        // If (a[i] < a[i+1]) then take
        // minimum and store in variable
        if (a[i] < a[i + 1]) {
            r = Math.min(r, Math.floor((a[i] + a[i + 1]) / 2));
        }
 
        // If (a[i]>a[i+1]) then take
        // maximum and store in
        // separate variable
        else if (a[i] > a[i + 1]) {
            l = Math.max(l, Math.ceil((a[i] + a[i + 1]) / 2));
        }
    }
 
    if (l > r) {
        console.log("-1");
    }
    else {
        console.log(l);
    }
}
 
// Driver function
var arr = [10, 5, 4, 3, 2, 1];
var n = arr.length;
 
// Function Call
findk(arr, n);
// This code is contributed by prasad264


Output

8



Time Complexity: O(n), iterating the loop for once only.
Auxiliary Space: O(1), no extra space is used.

Another Approach:

  • Find the maximum and minimum values in the array.
  • Perform binary search to find the value of K such that the absolute difference between adjacent elements of the resulting array is either 0 or 1.
  • In each iteration of binary search, calculate the absolute difference between adjacent elements of the resulting array.
  • If the absolute difference is greater than 1, set the search range accordingly.
  • If the absolute difference is less than or equal to 1, update the answer with the current value of K and set the search range accordingly.

C++




#include <bits/stdc++.h>
using namespace std;
 
int findK(int arr[], int n) {
    int lo = *min_element(arr, arr+n);
    int hi = *max_element(arr, arr+n);
    int ans = -1;
    while (lo <= hi) {
        int mid = lo + (hi - lo) / 2;
        bool valid = true;
        for (int i = 1; i < n; i++) {
            if (abs(arr[i] - mid) < abs(arr[i-1] - mid)) {
                valid = false;
                break;
            }
        }
        if (valid) {
            ans = mid;
            hi = mid - 1;
        } else {
            lo = mid + 1;
        }
    }
    return ans;
}
 
int main() {
    int arr[] = {10, 5, 4, 3, 2, 1};
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = findK(arr, n);
    if (k == -1) {
        cout << "No such K exists\n";
    } else {
        cout << k;
    }
    return 0;
}


Java




import java.util.Arrays;
 
public class Main {
   
  // Function to find K
    public static int findK(int[] arr, int n) {
       
      // Finding minimum and maximum from array
        int lo = Arrays.stream(arr).min().getAsInt();
        int hi = Arrays.stream(arr).max().getAsInt();
        int ans = -1;
       
      // Binary search to find value that absolute difference between adjacent element
      // of resulting array is either 0 or 1
        while (lo <= hi) {
            int mid = lo + (hi - lo) / 2;
            boolean valid = true;
           
          // Inner loop calculating the absolute differece between adjacent elements of the resulting
          // array.
            for (int i = 1; i < n; i++) {
                if (Math.abs(arr[i] - mid) < Math.abs(arr[i-1] - mid)) {
                    valid = false;
                    break;
                }
            }
           
          // if difference is less than 1 update value of ans.
            if (valid) {
                ans = mid;
                hi = mid - 1;
            } else {
                lo = mid + 1;
            }
        }
        return ans;
    }
 
    public static void main(String[] args) {
       
      // Input
        int[] arr = {10, 5, 4, 3, 2, 1};
        int n = arr.length;
        int k = findK(arr, n);
        if (k == -1) {
            System.out.println("No such K exists");
        } else {
            System.out.println(k);
        }
    }
}


Python3




import sys
 
def findK(arr, n):
    lo = min(arr)
    hi = max(arr)
    ans = -1
    while lo <= hi:
        mid = lo + (hi - lo) // 2
        valid = True
        for i in range(1, n):
            if abs(arr[i] - mid) < abs(arr[i-1] - mid):
                valid = False
                break
        if valid:
            ans = mid
            hi = mid - 1
        else:
            lo = mid + 1
    return ans
 
arr = [10, 5, 4, 3, 2, 1]
n = len(arr)
k = findK(arr, n)
if k == -1:
    print("No such K exists")
else:
    print(k)


C#




using System;
using System.Linq;
 
class Program
{
    static int FindK(int[] arr, int n)
    {
          // Finding min and max of array and store in lo and hi respectively
        int lo = arr.Min();
        int hi = arr.Max();
        int ans = -1;
       
          // Binary serach to find the element such that the difference
        // adjacent elements of the resulting array is either 0 or 1
        while (lo <= hi)
        {
            int mid = lo + (hi - lo) / 2;
            bool valid = true;
            for (int i = 1; i < n; i++)
            {
                if (Math.Abs(arr[i] - mid) < Math.Abs(arr[i - 1] - mid))
                {
                    valid = false;
                    break;
                }
            }
            if (valid)
            {
                ans = mid;
                hi = mid - 1;
            }
            else
            {
                lo = mid + 1;
            }
        }
       
          // Returning  ans
        return ans;
    }
 
          // Driver code
    static void Main(string[] args)
    {
        int[] arr = { 10, 5, 4, 3, 2, 1 };
        int n = arr.Length;
        int k = FindK(arr, n);
        if (k == -1)
        {
            Console.WriteLine("No such K exists");
        }
        else
        {
            Console.WriteLine(k);
        }
    }
}


Javascript




// Function to find K
function findK(arr, n) {
 
    // Finding minimum and maximum from array
    let lo = Math.min(...arr);
    let hi = Math.max(...arr);
    let ans = -1;
     
    // Binary search to find value that absolute difference between adjacent element
    // of resulting array is either 0 or 1
    while (lo <= hi) {
        let mid = lo + Math.floor((hi - lo) / 2);
        let valid = true;
         
        // Inner loop calculating the absolute differece between adjacent elements of the resulting
        // array.
        for (let i = 1; i < n; i++) {
            if (Math.abs(arr[i] - mid) < Math.abs(arr[i-1] - mid)) {
                valid = false;
                break;
            }
        }
         
        // if difference is less than 1 update value of ans.
        if (valid) {
            ans = mid;
            hi = mid - 1;
        } else {
            lo = mid + 1;
        }
    }
    return ans;
}
 
 
// Test case
let arr = [10, 5, 4, 3, 2, 1];
let n = arr.length;
let k = findK(arr, n);
if (k === -1) {
    console.log("No such K exists");
} else {
    console.log(k);
}


Output

8



Time Complexity: O(n log (hi – lo))

Auxiliary Space: O(1)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads