📜  计算给定数组中一系列索引 [L, R] 中存在的 1

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

给定一个数组arr[]由单个元素N ( 1 ≤ N ≤ 10 6 ) 和两个整数LR 组成, ( 1 ≤ L ≤ R ≤ 10 5 ),任务是使所有数组元素为01使用以下操作:

  • 从数组arr[] 中选择一个元素P使得P > 1
  • 用相同位置的三个元素依次替换Pfloor(P/2), P%2, floor(P/2 )。因此,每次操作后数组arr[]的大小增加2

执行所有操作后打印数组arr[]中索引[L, R]范围内1秒的总数。
注意:保证R不大于最终数组Arr的长度。

例子:

方法:按照以下步骤使用递归解决问题:

  • 遍历数组。
  • 声明一个函数FindSize(N)以在给定数组最初仅包含一个元素(即N)时查找修改后的数组的大小
  • 声明一个函数CountOnes(N)递归计算CountOnes(N / 2)N % 2CountOnes(N / 2)

以下是给定方法的实现:

C++14
// C++ Program to implement
// the above approach
 
#include 
using namespace std;
 
// Function to find the size of the
// array if the array initially
// contains a single element
int findSize(int N)
{
    // Base case
    if (N == 0)
        return 1;
    if (N == 1)
        return 1;
 
    int Size = 2 * findSize(N / 2) + 1;
 
    // P / 2 -> findSize(N / 2)
    // P % 2 -> 1
    // P / 2 -> findSize(N / 2)
    return Size;
}
 
// Function to return the count
// of 1s in the range [L, R]
int CountOnes(int N, int L, int R)
{
    if (L > R) {
        return 0;
    }
 
    // Base Case
    if (N <= 1) {
 
        return N;
    }
 
    int ret = 0;
    int M = N / 2;
    int Siz_M = findSize(M);
 
    // PART 1 -> N / 2
    // [1, Siz_M]
    if (L <= Siz_M) {
 
        // Update the right end point
        // of the range to min(Siz_M, R)
        ret += CountOnes(
            N / 2, L, min(Siz_M, R));
    }
 
    // PART 2 -> N % 2
    // [SizM + 1, Siz_M + 1]
    if (L <= Siz_M + 1 && Siz_M + 1 <= R) {
        ret += N % 2;
    }
 
    // PART 3 -> N / 2
    // [SizM + 2, 2 * Siz_M - 1]
    // Same as PART 1
    // Property of Symmetricity
    // Shift the coordinates according to PART 1
    // Subtract (Siz_M + 1) from both L, R
 
    if (Siz_M + 1 < R) {
        ret += CountOnes(N / 2,
                         max(1, L - Siz_M - 1),
                         R - Siz_M - 1);
    }
 
    return ret;
}
 
// Driver Code
int main()
{
    // Input
    int N = 7, L = 2, R = 5;
 
    // Counts the number of 1's in
    // the range [L, R]
    cout << CountOnes(N, L, R) << endl;
 
    return 0;
}


Java
// Java program to implement
// the above approach
import java.util.*;
class GFG
{
  
// Function to find the size of the
// array if the array initially
// contains a single element
static int findSize(int N)
{
     
    // Base case
    if (N == 0)
        return 1;
    if (N == 1)
        return 1;
    int Size = 2 * findSize(N / 2) + 1;
     
    // P / 2 -> findSize(N / 2)
    // P % 2 -> 1
    // P / 2 -> findSize(N / 2)
    return Size;
}
   
// Function to return the count
// of 1s in the range [L, R]
static int CountOnes(int N, int L, int R)
{
    if (L > R)
    {
        return 0;
    }
     
    // Base Case
    if (N <= 1)
    {
        return N;
    }  
    int ret = 0;
    int M = N / 2;
    int Siz_M = findSize(M);
   
    // PART 1 -> N / 2
    // [1, Siz_M]
    if (L <= Siz_M)
    {
         
        // Update the right end point
        // of the range to min(Siz_M, R)
        ret += CountOnes(N / 2, L,
                         Math.min(Siz_M, R));
    }
   
    // PART 2 -> N % 2
    // [SizM + 1, Siz_M + 1]
    if (L <= Siz_M + 1 && Siz_M + 1 <= R)
    {
        ret += N % 2;
    }
   
    // PART 3 -> N / 2
    // [SizM + 2, 2 * Siz_M - 1]
    // Same as PART 1
    // Property of Symmetricity
    // Shift the coordinates according to PART 1
    // Subtract (Siz_M + 1) from both L, R
    if (Siz_M + 1 < R)
    {
        ret += CountOnes(N / 2,
                         Math.max(1, L - Siz_M - 1),
                         R - Siz_M - 1);
    }
    return ret;
}
  
// Driver Code
public static void main(String[] args)
{
   
    // Input
    int N = 7, L = 2, R = 5;
     
    // Counts the number of 1's in
    // the range [L, R]
    System.out.println(CountOnes(N, L, R));
}
}
 
// This code is contributed by code_hunt.


Python3
# Python3 program to implement
# the above approach
 
# Function to find the size of the
# array if the array initially
# contains a single element
def findSize(N):
 
    # Base case
    if (N == 0):
        return 1
    if (N == 1):
        return 1
 
    Size = 2 * findSize(N // 2) + 1
 
    # P / 2 -> findSize(N // 2)
    # P % 2 -> 1
    # P / 2 -> findSize(N / 2)
    return Size
 
# Function to return the count
# of 1s in the range [L, R]
def CountOnes(N, L, R):
 
    if (L > R):
        return 0
 
    # Base Case
    if (N <= 1):
        return N
 
    ret = 0
    M = N // 2
    Siz_M = findSize(M)
 
    # PART 1 -> N / 2
    # [1, Siz_M]
    if (L <= Siz_M):
 
        # Update the right end point
        # of the range to min(Siz_M, R)
        ret += CountOnes(
            N // 2, L, min(Siz_M, R))
 
    # PART 2 -> N % 2
    # [SizM + 1, Siz_M + 1]
    if (L <= Siz_M + 1 and Siz_M + 1 <= R):
        ret += N % 2
 
    # PART 3 -> N / 2
    # [SizM + 2, 2 * Siz_M - 1]
    # Same as PART 1
    # Property of Symmetricity
    # Shift the coordinates according to PART 1
    # Subtract (Siz_M + 1) from both L, R
 
    if (Siz_M + 1 < R):
        ret += CountOnes(N // 2,
                         max(1, L - Siz_M - 1),
                         R - Siz_M - 1)
 
    return ret
 
# Driver Code
if __name__ == "__main__":
 
    # Input
    N = 7
    L = 2
    R = 5
 
    # Counts the number of 1's in
    # the range [L, R]
    print(CountOnes(N, L, R))
 
# This code is contributed by chitranayal


C#
// C# program to implement
// the above approach
using System;
 
class GFG{
 
// Function to find the size of the
// array if the array initially
// contains a single element
static int findSize(int N)
{
     
    // Base case
    if (N == 0)
        return 1;
    if (N == 1)
        return 1;
   
    int Size = 2 * findSize(N / 2) + 1;
     
    // P / 2 -> findSize(N / 2)
    // P % 2 -> 1
    // P / 2 -> findSize(N / 2)
    return Size;
}
   
// Function to return the count
// of 1s in the range [L, R]
static int CountOnes(int N, int L, int R)
{
    if (L > R)
    {
        return 0;
    }
     
    // Base Case
    if (N <= 1)
    {
        return N;
    }
   
    int ret = 0;
    int M = N / 2;
    int Siz_M = findSize(M);
   
    // PART 1 -> N / 2
    // [1, Siz_M]
    if (L <= Siz_M)
    {
         
        // Update the right end point
        // of the range to min(Siz_M, R)
        ret += CountOnes(N / 2, L,
                         Math.Min(Siz_M, R));
    }
   
    // PART 2 -> N % 2
    // [SizM + 1, Siz_M + 1]
    if (L <= Siz_M + 1 && Siz_M + 1 <= R)
    {
        ret += N % 2;
    }
   
    // PART 3 -> N / 2
    // [SizM + 2, 2 * Siz_M - 1]
    // Same as PART 1
    // Property of Symmetricity
    // Shift the coordinates according to PART 1
    // Subtract (Siz_M + 1) from both L, R
    if (Siz_M + 1 < R)
    {
        ret += CountOnes(N / 2,
                         Math.Max(1, L - Siz_M - 1),
                         R - Siz_M - 1);
    }
    return ret;
}
 
// Driver code
static void Main()
{
     
    // Input
    int N = 7, L = 2, R = 5;
     
    // Counts the number of 1's in
    // the range [L, R]
    Console.WriteLine(CountOnes(N, L, R));
}
}
 
// This code is contributed by divyesh072019


Javascript


输出:
4

时间复杂度: O(N)(使用大师定理,T(N) = 2 * T(N / 2) + 1 => T(N) = O(N))
辅助空间: O(N)

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