Find the value of K after replacing every index of the array by |ai – K|
Last Updated :
23 Aug, 2023
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++
#include <bits/stdc++.h>
using namespace std;
void findk( int a[], int n)
{
int l = 0, r = 1e9;
for ( int i = 0; i < n - 1; i++) {
if (a[i] < a[i + 1]) {
r = min(r, (a[i] + a[i + 1]) / 2);
}
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;
}
int main()
{
int arr[] = { 10, 5, 4, 3, 2, 1 };
int n = sizeof (arr) / sizeof (arr[0]);
findk(arr, n);
return 0;
}
|
Java
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)
{
int l = 0 ;
int r = 1000000000 ;
for ( int i = 0 ; i < n - 1 ; i++) {
if (arr[i] < arr[i + 1 ]) {
r = Math.min(r, (arr[i] + arr[i + 1 ]) / 2 );
}
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
def findk(a, n):
l = 0
r = 10 * * 9
for i in range (n - 1 ):
if (a[i] < a[i + 1 ]):
r = min (r, (a[i] + a[i + 1 ]) / / 2 )
elif (a[i] > a[i + 1 ]):
l = max (l, (a[i] + a[i + 1 ] + 1 ) / / 2 )
if (l > r):
print ( "-1" )
else :
print (l)
if __name__ = = '__main__' :
arr = [ 10 , 5 , 4 , 3 , 2 , 1 ]
n = len (arr)
findk(arr, n)
|
C#
using System;
public class GFG {
static public void Main()
{
int [] arr = { 10, 5, 4, 3, 2, 1 };
int n = arr.Length;
find(arr, n);
}
static void find( int [] arr, int n)
{
int l = 0;
int r = 1000000000;
for ( int i = 0; i < n - 1; i++)
{
if (arr[i] < arr[i + 1]) {
r = Math.Min(r, (arr[i] + arr[i + 1]) / 2);
}
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);
}
}
}
|
Javascript
function findk(a, n) {
let l = 0, r = 1e9;
for (let i = 0; i < n - 1; i++) {
if (a[i] < a[i + 1]) {
r = Math.min(r, Math.floor((a[i] + a[i + 1]) / 2));
}
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);
}
}
var arr = [10, 5, 4, 3, 2, 1];
var n = arr.length;
findk(arr, n);
|
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 {
public static int findK( int [] arr, int n) {
int lo = Arrays.stream(arr).min().getAsInt();
int hi = Arrays.stream(arr).max().getAsInt();
int ans = - 1 ;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2 ;
boolean 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 ;
}
}
return ans;
}
public 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 ) {
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)
{
int lo = arr.Min();
int hi = arr.Max();
int ans = -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;
}
}
return ans;
}
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 findK(arr, n) {
let lo = Math.min(...arr);
let hi = Math.max(...arr);
let ans = -1;
while (lo <= hi) {
let mid = lo + Math.floor((hi - lo) / 2);
let valid = true ;
for (let 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;
}
}
return ans;
}
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);
}
|
Time Complexity: O(n log (hi – lo))
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...