📌  相关文章
📜  N步获得K所需的递减操作计数

📅  最后修改于: 2021-04-22 10:08:48             🧑  作者: Mango

给定两个整数NK ,分别表示允许的操作数和执行N次操作后需要获得的数。考虑一个值S ,最初为0 ,任务是通过以任何方式执行N次以下操作将S转换为K

  1. S减去1
  2. P + 1加到S ,其中P是先前添加的数字(最初为0 )。

如果无法将S转换为K ,则打印-1 。否则,打印需要执行的减量操作数。
注意:每次执行操作后, S必须为正。

例子:

天真的方法:最简单的想法是在[1,N]范围内迭代一个循环并检查以下条件:

如果存在从范围I中的任何值[1,N]满足上述条件,则打印i的值。否则,打印“ -1”
时间复杂度: O(N),其中N是允许的最大步数。
辅助空间: O(1)

高效方法:为了优化上述方法,我们的想法是使用二进制搜索。步骤如下:

  1. 初始化两个变量,0开始,以N结束
  2. 通过取startend的平均值,找到上述两个变量的中间索引。
  3. 检查我们是否可以拥有类型1中等数量的步骤。如果是,则中途打印并停止迭代。
  4. 其他更新开始 结束 根据我们通过检查中点并从步骤2重复得到的结果。
  5. 如果不存在满足给定条件的中间部分,则打印“ -1”

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to check whether m number
// of steps of type 1 are valid or not
int isValid(int n, int m, int k)
{
 
    // If m and n are the count of operations
    // of type 1 and type 2 respectively,
    // then n - m operations are performed
    int step2 = n - m;
 
    // Find the value of S after step 2
    int cnt = (step2 * (step2 + 1)) / 2;
 
    // If m steps of type 1 is valid
    if (cnt - m == k)
        return 0;
 
    if (cnt - m > k)
        return 1;
 
    return -1;
}
 
// Function to find the number of
// operations of type 1 required
void countOfOperations(int n, int k)
{
    int start = 0, end = n;
    bool ok = 1;
 
    // Iterate over the range
    while (start <= end) {
 
        // Find the value of mid
        int mid = (start + end) / 2;
 
        // Check if m steps of type 1
        // are valid or not
        int temp = isValid(n, mid, k);
 
        // If mid is the valid
        // number of steps
        if (temp == 0) {
            ok = 0;
            cout << mid;
            break;
        }
 
        else if (temp == 1) {
            start = mid + 1;
        }
 
        else {
            end = mid - 1;
        }
    }
 
    // If no valid number
    // of steps exist
    if (ok)
        cout << "-1";
}
 
// Driver Code
int main()
{
    // Given and N, K
    int N = 5, K = 4;
 
    // Function Call
    countOfOperations(N, K);
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to check whether m number
// of steps of type 1 are valid or not
static int isValid(int n, int m, int k)
{
 
    // If m and n are the count of operations
    // of type 1 and type 2 respectively,
    // then n - m operations are performed
    int step2 = n - m;
 
    // Find the value of S after step 2
    int cnt = (step2 * (step2 + 1)) / 2;
 
    // If m steps of type 1 is valid
    if (cnt - m == k)
    return 0;
 
    if (cnt - m > k)
        return 1;
 
    return -1;
}
 
// Function to find the number of
// operations of type 1 required
static void countOfOperations(int n, int k)
{
    int start = 0, end = n;
    boolean ok = true;
 
    // Iterate over the range
    while (start <= end)
    {
         
        // Find the value of mid
        int mid = (start + end) / 2;
 
        // Check if m steps of type 1
        // are valid or not
        int temp = isValid(n, mid, k);
 
        // If mid is the valid
        // number of steps
        if (temp == 0)
        {
            ok = false;
            System.out.print(mid);
            break;
        }
 
        else if (temp == 1)
        {
            start = mid + 1;
        }
        else
        {
            end = mid - 1;
        }
    }
 
    // If no valid number
    // of steps exist
    if (ok)
        System.out.print("-1");
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given and N, K
    int N = 5, K = 4;
 
    // Function call
    countOfOperations(N, K);
}
}
 
// This code is contributed by gauravrajput1


Python3
# Python3 program for the above approach
 
# Function to check whether m number
# of steps of type 1 are valid or not
def isValid(n, m, k):
 
    # If m and n are the count of operations
    # of type 1 and type 2 respectively,
    # then n - m operations are performed
    step2 = n - m
 
    # Find the value of S after step 2
    cnt = (step2 * (step2 + 1)) // 2
 
    # If m steps of type 1 is valid
    if (cnt - m == k):
        return 0
 
    if (cnt - m > k):
        return 1
 
    return -1
 
# Function to find the number of
# operations of type 1 required
def countOfOperations(n, k):
 
    start = 0
    end = n
    ok = 1
 
    # Iterate over the range
    while(start <= end):
 
        # Find the value of mid
        mid = (start + end) // 2
 
        # Check if m steps of type 1
        # are valid or not
        temp = isValid(n, mid, k)
 
        # If mid is the valid
        # number of steps
        if (temp == 0):
            ok = 0
            print(mid)
            break
 
        elif (temp == 1):
            start = mid + 1
        else:
            end = mid - 1
 
    # If no valid number
    # of steps exist
    if (ok):
        print("-1")
 
# Driver Code
 
# Given and N, K
N = 5
K = 4
 
# Function call
countOfOperations(N, K)
 
# This code is contributed by Shivam Singh


C#
// C# program for
// the above approach
using System;
class GFG{
 
// Function to check
// whether m number of steps
// of type 1 are valid or not
static int isValid(int n,
                   int m, int k)
{
  // If m and n are the
  // count of operations
  // of type 1 and type 2
  // respectively, then n - m
  // operations are performed
  int step2 = n - m;
 
  // Find the value of S
  // after step 2
  int cnt = (step2 *
            (step2 + 1)) / 2;
 
  // If m steps of
  // type 1 is valid
  if (cnt - m == k)
    return 0;
 
  if (cnt - m > k)
    return 1;
 
  return -1;
}
 
// Function to find the
// number of operations
// of type 1 required 
static void countOfOperations(int n,
                              int k)
{
  int start = 0, end = n;
  bool ok = true;
 
  // Iterate over the range
  while (start <= end)
  {
    // Find the value of mid
    int mid = (start + end) / 2;
 
    // Check if m steps of type 1
    // are valid or not
    int temp = isValid(n, mid, k);
 
    // If mid is the valid
    // number of steps
    if (temp == 0)
    {
      ok = false;
      Console.Write(mid);
      break;
    }
 
    else if (temp == 1)
    {
      start = mid + 1;
    }
    else
    {
      end = mid - 1;
    }
  }
 
  // If no valid number
  // of steps exist
  if (ok)
    Console.Write("-1");
}
 
// Driver Code
public static void Main(String[] args)
{
  // Given and N, K
  int N = 5, K = 4;
 
  // Function call
  countOfOperations(N, K);
}
}
 
// This code is contributed by Amit Katiyar


输出:
2


时间复杂度: O(log 2 N),其中N是给定的步骤
空间复杂度: O(1)