📌  相关文章
📜  最多执行 K 次给定操作后,1 到 N 序列中的最大反转

📅  最后修改于: 2021-09-07 02:33:23             🧑  作者: Mango

给定两个整数NK ,任务是在执行最大K 次操作后,在前N 个自然数的序列中找到最大反演次数。在每个操作中,可以交换序列中的任意两个元素。注意:序列中的元素是按升序排列的,序列中没有重复的元素。
例子:

方法:

  1. 因为按升序排列的元素是完美的,即它有0倒置,而按降序排列的元素是最不完美的,即它有最大的倒置。
  2. 因此,我们的想法是使每个交换操作的序列更接近降序,以获得最大的反转。因此,在第一次操作中,我们需要交换最大和最小元素。同样,在第i 个操作中,我们需要将第 i 个最大的元素与序列的第 i 个最小的元素交换。
  3. 将升序转换为降序所需的交换次数为N/2 。因此,执行的操作次数应小于或等于N/2
    因此将 K 更新为:
  1. 我们需要维护两个变量‘left’‘right’分别表示序列的第 i 个最小元素和第 i 个最大元素。
  2. ‘left’初始化为1 ,将‘right’初始化为N
  3. 我们需要执行以下操作,直到K变为 0:
    • On,在反转的序列号中交换‘左’‘右’增加
  • 因此,将此值添加到答案中。
    • 这是因为当我们交换 ‘left’ 和 ‘right’ 时,形式 (right, i) 的所有对都有助于反转,而且形式 (i, left) 的所有对都有助于反转,其中 left < i <正确的。
    • 形式对的总数(right, i) => right – left, where left <= i < right
    • (i, left) => right – left 形式的对的总数,其中 left< i <=right
    • 此类对的总数为2 * ( right – left )
    • 我们从中减去 1,因为在上面的计算中(右,左)被计算了两次。
  • K“右”的值减少1 ,将“左”的值增加 1。
  1. 打印答案的值

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function which computes the
// maximum number of inversions
int maximum_inversion(int n, int k)
{
    // 'answer' will store the required
    // number of inversions
    int answer = 0;
 
    // We do this because we will
    // never require more than
    // floor(n/2) operations
    k = min(k, n / 2);
 
    // left pointer in the array
    int left = 1;
    // right pointer in the array
    int right = n;
 
    // Doing k operations
    while (k--) {
        // Incrementing ans by number
        // of inversions increase due
        // to this swapping
        answer += 2 * (right - left) - 1;
        left++;
        right--;
    }
    cout << answer << endl;
}
 
// Driver code
int main()
{
    // Input 1
    int N = 5;
    int K = 3;
    maximum_inversion(N, K);
 
    // Input 2
    N = 4;
    K = 1;
    maximum_inversion(N, K);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
     
// Function which computes the
// maximum number of inversions
static void maximum_inversion(int n, int k)
{
     
    // 'answer' will store the required
    // number of inversions
    int answer = 0;
 
    // We do this because we will
    // never require more than
    // floor(n/2) operations
    k = Math.min(k, n / 2);
 
    // left pointer in the array
    int left = 1;
     
    // right pointer in the array
    int right = n;
 
    // Doing k operations
    while (k != 0)
    {
        k--;
         
        // Incrementing ans by number
        // of inversions increase due
        // to this swapping
        answer += 2 * (right - left) - 1;
        left++;
        right--;
    }
    System.out.println(answer);
}
 
// Driver Code
public static void main(String s[])
{
     
    // Input 1
    int N = 5;
    int K = 3;
    maximum_inversion(N, K);
     
    // Input 2
    N = 4;
    K = 1;
    maximum_inversion(N, K);
}
}
 
// This code is contributed by rutvik_56


Python3
# Python3 program for the above approach
 
# Function which computes the
# maximum number of inversions
def maximum_inversion(n, k):
     
    # 'answer' will store the required
    # number of inversions
    answer = 0;
 
    # We do this because we will
    # never require more than
    # floor(n/2) operations
    k = min(k, n // 2);
 
    # left pointer in the array
    left = 1;
 
    # right pointer in the array
    right = n;
 
    # Doing k operations
    while (k > 0):
        k -= 1;
 
        # Incrementing ans by number
        # of inversions increase due
        # to this swapping
        answer += 2 * (right - left) - 1;
        left += 1;
        right -= 1;
 
    print(answer);
 
# Driver Code
if __name__ == '__main__':
     
    # Input 1
    N = 5;
    K = 3;
    maximum_inversion(N, K);
 
    # Input 2
    N = 4;
    K = 1;
    maximum_inversion(N, K);
 
# This code is contributed by amal kumar choubey


C#
// C# program for the above approach
using System;
 
class GFG{
     
// Function which computes the
// maximum number of inversions
static void maximum_inversion(int n, int k)
{
     
    // 'answer' will store the required
    // number of inversions
    int answer = 0;
 
    // We do this because we will
    // never require more than
    // floor(n/2) operations
    k = Math.Min(k, n / 2);
 
    // left pointer in the array
    int left = 1;
     
    // right pointer in the array
    int right = n;
 
    // Doing k operations
    while (k != 0)
    {
        k--;
         
        // Incrementing ans by number
        // of inversions increase due
        // to this swapping
        answer += 2 * (right - left) - 1;
        left++;
        right--;
    }
    Console.WriteLine(answer);
}
 
// Driver Code
public static void Main(String []s)
{
     
    // Input 1
    int N = 5;
    int K = 3;
    maximum_inversion(N, K);
     
    // Input 2
    N = 4;
    K = 1;
    maximum_inversion(N, K);
}
}
 
// This code is contributed by Rohit_ranjan


Javascript


输出:
10
5

时间复杂度: O(K)
辅助空间: O(1)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live