Given four numbers N, L, R, and S, the task is to find a permutation of first N natural numbers(1-based indexing) having the sum as S from index L to R. If there are multiple permutations, then print any of them. Otherwise, print -1.
Examples:
Input: N = 6, L = 3, R = 5, S = 8 Output: 3 4 5 2 1 6 Explanation: The output permutation has 5 at index L and 1 at index R. The sum of the numbers from L to R is 8(5+2+1).
Input: N = 4, L = 2, R = 3, S = 2 Output: -1 Explanation: There does not exist any permutation in which the sum of numbers from index L to R is S.
Approach: The given problem can be solved by using the Greedy Approach which is based on the observation that suppose X numbers have to be chosen from a permutation of first N natural numbers, so to make the sum as S, let the minimum and maximum sum of X numbers are minSum and maxSum respectively, then:
X = R – L + 1 minSum = X(X + 1)/2 maxSum = X(2*N + 1 – X)/2
Thus, if the given sum S lies in the range [minSum, maxSum], then there exists a permutation such that the sum of all numbers from L to R is S. Otherwise, there does not exist any such permutation. Follow the steps below to solve the problem:
- Define a function possible(int x, int S, int N) and perform the following tasks:
- Initialize the variable minSum as x*(x + 1)/2 and maxSum as (x * ((2*N) – x + 1))/2.
- If S is less than minSum or S is greater than maxSum then return false. Otherwise, return true.
- Initialize the variable, say x as (R – L + 1).
- If the value returned by the function possible(x, S, N) returns false, then print -1 and return from the function.
- Otherwise, initialize a vector v[] to store the numbers present within the given segment.
- Iterate over the range [N, 1] using the variable i and perform the following tasks:
- If S does not equal 0 then print -1 and return.
- Initialize a vector, say v1[] to store the numbers which are not present within the given segment.
- Iterate over the range [1, N] using the variable i and initialize a vector iterator it and check if the element i is present in the vector v[] using the find() or not. If it is not present then push it into the vector v1.
- Initialize the variables j and f as 0 to print the results.
- Iterate over the range [1, L) using the variable i and print the value of v1[j], and increase the value of j by 1.
- Iterate over the range [L, R] using the variable i and print the value of v[f], and increase the value of f by 1.
- Iterate over the range [R+1, N] using the variable i and print the value of v1[j], and increase the value of j by 1.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool possible( int x, int S, int N)
{
int minSum = (x * (x + 1)) / 2;
int maxSum = (x * ((2 * N) - x + 1)) / 2;
if (S < minSum || S > maxSum) {
return false ;
}
return true ;
}
void findPermutation( int N, int L,
int R, int S)
{
int x = R - L + 1;
if (!possible(x, S, N)) {
cout << -1;
return ;
}
else {
vector< int > v;
for ( int i = N; i >= 1; --i) {
if ((S - i) >= 0
&& possible(x - 1, S - i,
i - 1)) {
S = S - i;
x--;
v.push_back(i);
}
if (S == 0) {
break ;
}
}
if (S != 0) {
cout << -1;
return ;
}
vector< int > v1;
for ( int i = 1; i <= N; ++i) {
vector< int >::iterator it
= find(v.begin(), v.end(), i);
if (it == v.end()) {
v1.push_back(i);
}
}
int j = 0, f = 0;
for ( int i = 1; i < L; ++i) {
cout << v1[j] << " " ;
j++;
}
for ( int i = L; i <= R; ++i) {
cout << v[f] << " " ;
f++;
}
for ( int i = R + 1; i <= N; ++i) {
cout << v1[j] << " " ;
j++;
}
}
return ;
}
int main()
{
int N = 6, L = 3, R = 5, S = 8;
findPermutation(N, L, R, S);
return 0;
}
|
Java
import java.util.ArrayList;
class GFG{
public static boolean possible( int x, int S, int N)
{
int minSum = (x * (x + 1 )) / 2 ;
int maxSum = (x * (( 2 * N) - x + 1 )) / 2 ;
if (S < minSum || S > maxSum) {
return false ;
}
return true ;
}
public static void findPermutation( int N, int L,
int R, int S)
{
int x = R - L + 1 ;
if (!possible(x, S, N)) {
System.out.print(- 1 );
return ;
}
else {
ArrayList<Integer> v = new ArrayList<>();
for ( int i = N; i >= 1 ; --i) {
if ((S - i) >= 0
&& possible(x - 1 , S - i,
i - 1 )) {
S = S - i;
x--;
v.add(i);
}
if (S == 0 ) {
break ;
}
}
if (S != 0 ) {
System.out.print(- 1 );
return ;
}
ArrayList<Integer> v1 = new ArrayList<Integer>();
for ( int i = 1 ; i <= N; ++i) {
boolean it = v.contains(i);
if (!it) {
v1.add(i);
}
}
int j = 0 , f = 0 ;
for ( int i = 1 ; i < L; ++i) {
System.out.print(v1.get(j) + " " );
j++;
}
for ( int i = L; i <= R; ++i) {
System.out.print(v.get(f) + " " );
f++;
}
for ( int i = R + 1 ; i <= N; ++i) {
System.out.print(v1.get(j) + " " );
j++;
}
}
return ;
}
public static void main(String args[])
{
int N = 6 , L = 3 , R = 5 , S = 8 ;
findPermutation(N, L, R, S);
}
}
|
Python3
def possible(x, S, N):
minSum = (x * (x + 1 )) / / 2
maxSum = (x * (( 2 * N) - x + 1 )) / / 2
if (S < minSum or S > maxSum):
return False
return True
def findPermutation(N, L, R, S):
x = R - L + 1
if ( not possible(x, S, N)):
print ( "-1" )
return
else :
v = []
for i in range (N, 0 , - 1 ):
if ((S - i) > = 0 and possible(x - 1 , S - i, i - 1 )):
S = S - i
x - = 1
v.append(i)
if (S = = 0 ):
break
if (S ! = 0 ):
print ( - 1 )
return
v1 = []
for i in range ( 1 , N + 1 ):
it = i in v
if ( not it):
v1.append(i)
j = 0
f = 0
for i in range ( 1 , L):
print (v1[j], end = " " )
j + = 1
for i in range (L, R + 1 ):
print (v[f], end = " " )
f + = 1
for i in range (R + 1 , N + 1 ):
print (v1[j], end = " " )
j + = 1
return
if __name__ = = "__main__" :
N = 6
L = 3
R = 5
S = 8
findPermutation(N, L, R, S)
|
C#
using System;
using System.Collections.Generic;
class GFG {
public static bool possible( int x, int S, int N)
{
int minSum = (x * (x + 1)) / 2;
int maxSum = (x * ((2 * N) - x + 1)) / 2;
if (S < minSum || S > maxSum) {
return false ;
}
return true ;
}
public static void findPermutation( int N, int L, int R,
int S)
{
int x = R - L + 1;
if (!possible(x, S, N)) {
Console.WriteLine(-1);
return ;
}
else {
List< int > v = new List< int >();
for ( int i = N; i >= 1; --i) {
if ((S - i) >= 0
&& possible(x - 1, S - i, i - 1)) {
S = S - i;
x--;
v.Add(i);
}
if (S == 0) {
break ;
}
}
if (S != 0) {
Console.WriteLine(-1);
return ;
}
List< int > v1 = new List< int >();
for ( int i = 1; i <= N; ++i) {
bool it = v.Contains(i);
if (!it) {
v1.Add(i);
}
}
int j = 0, f = 0;
for ( int i = 1; i < L; ++i) {
Console.Write(v1[j] + " " );
j++;
}
for ( int i = L; i <= R; ++i) {
Console.Write(v[f] + " " );
f++;
}
for ( int i = R + 1; i <= N; ++i) {
Console.Write(v1[j] + " " );
j++;
}
}
return ;
}
public static void Main()
{
int N = 6, L = 3, R = 5, S = 8;
findPermutation(N, L, R, S);
}
}
|
Javascript
<script>
function possible(x, S, N) {
let minSum = (x * (x + 1)) / 2;
let maxSum = (x * (2 * N - x + 1)) / 2;
if (S < minSum || S > maxSum) {
return false ;
}
return true ;
}
function findPermutation(N, L, R, S) {
let x = R - L + 1;
if (!possible(x, S, N)) {
document.write(-1);
return ;
} else {
let v = [];
for (let i = N; i >= 1; --i) {
if (S - i >= 0 && possible(x - 1, S - i, i - 1)) {
S = S - i;
x--;
v.push(i);
}
if (S == 0) {
break ;
}
}
if (S != 0) {
document.write(-1);
return ;
}
let v1 = [];
for (let i = 1; i <= N; ++i) {
it = v.includes(i);
if (!it) {
v1.push(i);
}
}
let j = 0,
f = 0;
for (let i = 1; i < L; ++i) {
document.write(v1[j] + " " );
j++;
}
for (let i = L; i <= R; ++i) {
document.write(v[f] + " " );
f++;
}
for (let i = R + 1; i <= N; ++i) {
document.write(v1[j] + " " );
j++;
}
}
return ;
}
let N = 6,
L = 3,
R = 5,
S = 8;
findPermutation(N, L, R, S);
</script>
|
Time Complexity: O(N2) Auxiliary Space: O(N)
|