Find permutation of numbers upto N with a specific sum in a specific range
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.
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
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:
3 4 5 2 1 6
Time Complexity: O(N2)
Auxiliary Space: O(N)