查找范围 [L, R] 中具有 X 峰和 Y 谷的数字的排列
给定整数L、R、X和Y ,使得 (R > L ≥ 1)、(X ≥ 0) 和 (Y ≥ 0)。求范围[L, R]中数字的排列,使得排列中恰好存在X 峰和Y 谷。如果找到排列,则打印 Yes 和排列。否则打印编号。
注意:在数组arr[]中,如果arr[i-1] < arr[i] > arr[i+1]在第i 个索引处有一个峰值,如果 arr[i-1] > arr [ i 在第 i 个索引处有一个谷值] < arr[i+1],其中0< i < N 。
例子:
Input: L = 1, R = 3, X = 1, Y = 0
Output: Yes, arr[] = { 1, 3, 2 }
Explanation: 1 peak is required and no valley is required.
Clearly arr[0] < arr[1] > arr[2], arr[1] is the peak.
Input: L = 4, R = 8, X = 4, Y = 1
Output: No
Explanation: There is no such permutation of size 5 with 4 peaks and 1 valley.
Input: L = 3, R = 5, X = 0, Y = 0
Output: Yes, arr[] = { 3, 4, 5 }
Explanation: 0 peaks and 0 valleys are required.
The sorted array has no peak or valley.
处理方法:可以有以下五种情况。遵循针对每种情况提到的方法。
Case-1(没有可能的排列):排列的第一个和最后一个元素对峰和谷的数量没有贡献。
- 因此,如果(X + Y) > (R – L – 1)将不存在满足峰和谷数的排列。
- 此外,如果(X – Y) > 1的绝对值,则不会有这样的排列,因为两个峰之间正好有 1 个谷,反之亦然。
案例2(X = 0,Y = 0):按照下面提到的步骤。
- 创建一个大小为(R – L + 1)的数组arr[]并将范围[L, R]中的数字按排序顺序存储在数组中。
- 打印数组。
Case-3(X > Y):按照以下步骤进行:
- 创建一个大小为(R – L + 1)的数组arr[] ,该数组由[L, R]范围内的数字按排序顺序组成。
- 考虑最后 (X + Y – 1) 个元素来分配X峰和Y谷。
- 从i = (N – 2)迭代到i = (N – (X + Y – 1)) 。其中N = (R – L + 1)
- 在每次迭代中,将 arr[i] 与 arr[i+1] 交换,并将i减 2。
- 打印数组
案例 4(X < Y):按照以下步骤操作:
- 创建一个大小为(R – L + 1)的数组arr[] ,该数组由[L, R]范围内的数字按排序顺序组成。
- 考虑首先(X + Y)元素来分配X峰和Y谷。
- 从i = 1迭代到i = (X+Y) 。
- 对于每次迭代,将 arr[i] 与 arr[i-1] 交换,并将i增加 2。
- 打印数组。
案例 5(X = Y):按照以下步骤操作:
- 创建一个长度为(R – L + 1)的数组arr[] ,该数组由[L, R]范围内的数字按排序顺序组成。
- 考虑首先(X+Y)元素来分配(X-1)峰和Y谷。
- 从i = 1迭代到i = (X+Y)。
- 对于每次迭代,将 arr[i] 与 arr[i-1] 交换,并将i增加 2。
- 迭代完成后,交换数组的最后两个元素以获得更多峰值。
- 打印数组。
下面给出了上述方法的实现:
C++
// C++ code to implement the above approach
#include
using namespace std;
// Utility function to build the permutation
void BuildMountainArray(int L, int R, int X, int Y)
{
int N = (R - L + 1);
// Case-1: permutation cannot be built
if (((X + Y) > (N - 2)) || abs(X - Y) > 1) {
cout << "No" << endl;
}
else {
// Vector to store the permutation
vector res(N, 0);
for (int index = 0; index < N;
index++) {
res[index] = L + index;
}
// Case-2: X = 0, Y = 0
if (X == 0 && Y == 0) {
cout << "Yes" << endl;
for (int index = 0; index < N;
index++) {
cout << res[index] << " ";
}
cout << endl;
return;
}
// Case-3: X > Y
// Consider last (X+Y+1) elements
else if (X > Y) {
for (int index = N - 2;
index >= (N - (X + Y + 1));
index -= 2) {
swap(res[index],
res[index + 1]);
}
}
// Case-4: X < Y
// Consider first (X+Y) elements
else if (Y > X) {
for (int index = 1; index <=
(X + Y); index += 2) {
swap(res[index],
res[index - 1]);
}
}
else {
// Case-5: X = Y
// Consider first (X+Y) elements,
// it will give (X-1) peaks
// and Y valleys
for (int index = 1; index <=
(X + Y); index += 2) {
swap(res[index],
res[index - 1]);
}
// Swap last 2 elements,
// to get 1 more peak
swap(res[N - 2], res[N - 1]);
}
// Print the required array
cout << "Yes" << endl;
for (int index = 0; index < N;
index++) {
cout << res[index] << " ";
}
cout << endl;
}
}
// Driver code
int main()
{
// Input
int L = 1, R = 3, X = 1, Y = 0;
// Function call
BuildMountainArray(L, R, X, Y);
return 0;
}
Java
// Java code for the above approach
import java.io.*;
class GFG {
// Utility function to build the permutation
static void BuildMountainArray(int L, int R, int X,
int Y)
{
int N = (R - L + 1);
// Case-1: permutation cannot be built
if (((X + Y) > (N - 2)) || Math.abs(X - Y) > 1) {
System.out.println("No");
}
else
{
// Vector to store the permutation
int res[] = new int[N];
for (int index = 0; index < N; index++) {
res[index] = L + index;
}
// Case-2: X = 0, Y = 0
if (X == 0 && Y == 0) {
System.out.println("Yes");
for (int index = 0; index < N; index++) {
System.out.print(res[index] + " ");
}
System.out.println();
return;
}
// Case-3: X > Y
// Consider last (X+Y+1) elements
else if (X > Y) {
for (int index = N - 2;
index >= (N - (X + Y + 1));
index -= 2) {
int temp = res[index];
res[index] = res[index + 1];
res[index + 1] = temp;
}
}
// Case-4: X < Y
// Consider first (X+Y) elements
else if (Y > X) {
for (int index = 1; index <= (X + Y);
index += 2) {
int temp = res[index];
res[index] = res[index - 1];
res[index - 1] = temp;
}
}
else {
// Case-5: X = Y
// Consider first (X+Y) elements,
// it will give (X-1) peaks
// and Y valleys
for (int index = 1; index <= (X + Y);
index += 2) {
int temp = res[index];
res[index] = res[index - 1];
res[index - 1] = temp;
}
// Swap last 2 elements,
// to get 1 more peak
int temp = res[N - 2];
res[N - 2] = res[N - 1];
res[N - 1] = temp;
}
// Print the required array
System.out.println("Yes");
for (int index = 0; index < N; index++) {
System.out.print(res[index] + " ");
}
System.out.println();
}
}
// Driver code
public static void main(String[] args)
{
// Input
int L = 1, R = 3, X = 1, Y = 0;
// Function call
BuildMountainArray(L, R, X, Y);
}
}
// This code is contributed by Potta Lokesh
Python3
# Python code to implement the above approach
import math as Math
# Utility function to build the permutation
def BuildMountainArray(L, R, X, Y):
N = (R - L + 1)
# Case-1: permutation cannot be built
if (((X + Y) > (N - 2)) or Math.fabs(X - Y) > 1):
print("No")
else:
# Vector to store the permutation
res = [0] * N
for index in range(N):
res[index] = L + index
# Case-2: X = 0, Y = 0
if (X == 0 and Y == 0):
print("Yes")
for index in range(N):
print(res[index], end=" ")
print("")
return
# Case-3: X > Y
# Consider last (X+Y+1) elements
elif (X > Y):
for index in range(N - 2, N - (X + Y + 1) - 1, -2):
temp = res[index]
res[index] = res[index + 1]
res[index + 1] = temp
# Case-4: X < Y
# Consider first (X+Y) elements
elif (Y > X):
for index in range(1, X + Y + 1, 2):
temp = res[index]
res[index] = res[index - 1]
res[index - 1] = temp
else:
# Case-5: X = Y
# Consider first (X+Y) elements,
# it will give (X-1) peaks
# and Y valleys
for index in range(1, X + Y + 1, 2):
temp = res[index]
res[index] = res[index - 1]
res[index - 1] = temp
# Swap last 2 elements,
# to get 1 more peak
temp = res[N - 2]
res[N - 2] = res[N - 1]
res[N - 1] = temp
# Print the required array
print("Yes")
for index in range(N):
print(res[index], end=" ")
print("")
# Driver code
# Input
L = 1
R = 3
X = 1
Y = 0
# Function call
BuildMountainArray(L, R, X, Y)
# This code is contributed by Saurabh jaiswal
C#
// C# implementation of above approach
using System;
using System.Collections;
using System.Collections.Generic;
class GFG {
// Utility function to build the permutation
static void BuildMountainArray(int L, int R, int X,
int Y)
{
int N = (R - L + 1);
// Case-1: permutation cannot be built
if (((X + Y) > (N - 2)) || Math.Abs(X - Y) > 1) {
Console.WriteLine("No");
}
else
{
// Vector to store the permutation
int[] res = new int[N];
for (int index = 0; index < N; index++) {
res[index] = L + index;
}
// Case-2: X = 0, Y = 0
if (X == 0 && Y == 0) {
Console.WriteLine("Yes");
for (int index = 0; index < N; index++) {
Console.Write(res[index] + " ");
}
Console.WriteLine();
return;
}
// Case-3: X > Y
// Consider last (X+Y+1) elements
else if (X > Y) {
for (int index = N - 2;
index >= (N - (X + Y + 1));
index -= 2) {
int temp1 = res[index];
res[index] = res[index + 1];
res[index + 1] = temp1;
}
}
// Case-4: X < Y
// Consider first (X+Y) elements
else if (Y > X) {
for (int index = 1; index <= (X + Y);
index += 2) {
int temp2 = res[index];
res[index] = res[index - 1];
res[index - 1] = temp2;
}
}
else
{
// Case-5: X = Y
// Consider first (X+Y) elements,
// it will give (X-1) peaks
// and Y valleys
for (int index = 1; index <= (X + Y);
index += 2) {
int temp3 = res[index];
res[index] = res[index - 1];
res[index - 1] = temp3;
}
// Swap last 2 elements,
// to get 1 more peak
int temp4 = res[N - 2];
res[N - 2] = res[N - 1];
res[N - 1] = temp4;
}
// Print the required array
Console.WriteLine("Yes");
for (int index = 0; index < N; index++) {
Console.Write(res[index] + " ");
}
Console.WriteLine();
}
}
// Driver Code
public static void Main()
{
// Input
int L = 1, R = 3, X = 1, Y = 0;
// Function call
BuildMountainArray(L, R, X, Y);
}
}
// This code is contributed sanjoy_62.
Javascript
Yes
1 3 2
时间复杂度: O(N) 其中 N = (R – L + 1)
空间复杂度: O(1)