给定三个正整数L 、 R和K ,任务是找到范围[L, R]中在其二进制表示中有K个连续设置位的数字的计数。
例子:
Input: L = 4, R = 15, K = 3
Output: 3
Explanation:
Numbers whose binary representation contains K(=3) consecutive set bits are:
(7)10 = (111)2
(14)10 = (1110)2
(15)10 = (1111)2
Therefore, the required output is 3.
Input: L = 8, R = 100, K = 3
Output: 27
朴素方法:解决此问题的最简单方法是遍历范围[L, R]内所有可能的整数,并针对每个数字检查该数字的二进制表示是否包含 K 个连续的 1。如果发现是真的,则打印数字。
时间复杂度: O((R – L + 1) * 32)
辅助空间: O(1)
高效方法:该问题可以使用 Digit DP 解决。这个想法是计算[1, R]范围内具有K个连续1的数字,并减去范围[1, L – 1] 中具有K个连续1的数字的计数。以下是递推关系:
[Tex]= \sum^{1}_{i=0} cntN1X(len + 1, cntOne + i, KOne | (cntOne == K)) [/Tex]
cntN1X(len, cntOne, KOne): Stores the count of numbers in the range [1, X] with the following constraints:
len = length of binary representation of X.
cntOne = Count of consecutive 1s till index len.
KOne = Boolean value to check if K consecutive 1s present in X or not.
请按照以下步骤解决问题:
- 初始化一个 4D 数组dp[len][cntOne][KOne][tight]来计算和存储上述递推关系的所有子问题的值。
- 最后,返回dp[len][cntOne][KOne][tight] 的值。
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Function to find the count of numbers in
// range[1, X] having K consecutive set bits
int cntN1X(string str, int len, int K,
int cntOne, int dp[32][32][2][2],
bool KOne, bool tight)
{
// If length of current number is
// equal to length of string
if (len == str.length()) {
// If count of consecutive set bits
// in the current string is >= K
return (KOne == 1);
}
// If already computedx
// equal occurred
if (dp[len][cntOne][KOne][tight]
!= -1) {
return dp[len][cntOne][KOne][tight];
}
// If tight is 1, then element present
// at current index is element present
// in str at current index. Otherwise, 1.
int end = tight ? (str[len] - '0'): 1;
// Stores count of numbers whose
// len th bit is i.
int res = 0;
// Iterate over all possible
// value present at current index.
for(int i = 0; i <= end; i++) {
// Stores count of consecutive 1s
int temp = (i==1) ? (cntOne + 1): 0;
// Update res.
res += cntN1X(str, len + 1,
K, temp, dp, (KOne | (temp == K)),
(tight & (i==end)));
}
return dp[len][cntOne][KOne][tight]
= res;
}
// Function to find
// binary representation of N
string convertBinary(int N)
{
// Stores binary
// representation of N.
string res;
// Traverse each bit of N.
while(N) {
// Append current bit
// in res
res.push_back(N % 2 + '0');
// Update N.
N /= 2;
}
// Append 0 in binary representation
// Of N
while(res.length() < 32) {
res.push_back('0');
}
// Reverse binary representation of N
reverse(res.begin(), res.end());
return res;
}
// Function to count numbers in
// range[L, R] having K consecutive 1s.
int cntN1XL_R(int L, int R, int K)
{
// Stores binary representation
// of (L - 1)
string Ls = convertBinary(L - 1);
// Stores binary representation
// of R
string Rs = convertBinary(R);
// Stores values of overlapping
// subproblems
int dp[32][32][2][2];
// Initialize dp[][][][] array.
memset(dp, -1, sizeof(dp));
// Stores count of numbers from
// [1, L - 1] having K consecutive 1s
int resL = cntN1X(Ls, 0, K, 0,
dp, 0,1);
// Initialize dp[][][][] array.
memset(dp, -1, sizeof(dp));
// Stores count of numbers from
// [1, R - 1] having K consecutive 1s
int resR = cntN1X(Rs, 0, K, 0,
dp, 0, 1);
// Return total counts having K
// consecutive 1s in range[L, R]
return (resR - resL);
}
// Driver Code
int main()
{
int L = 8;
int R = 100;
int K = 3;
cout<
Java
// Java program to implement
// the above approach
import java.util.*;
class GFG{
// Function to find the count of numbers in
// range[1, X] having K consecutive set bits
public static int cntN1X(String str, int len, int K,
int cntOne, int dp[][][][],
int KOne, int tight)
{
// If length of current number is
// equal to length of string
if (len == str.length())
{
// If count of consecutive set bits
// in the current string is >= K
return (KOne == 1) ? 1 : 0;
}
// If already computedx
// equal occurred
if (dp[len][cntOne][KOne][tight] != -1)
{
return dp[len][cntOne][KOne][tight];
}
// If tight is 1, then element present
// at current index is element present
// in str at current index. Otherwise, 1.
int end = (tight == 1) ?
(str.charAt(len) - '0') : 1;
// Stores count of numbers whose
// len th bit is i.
int res = 0;
// Iterate over all possible
// value present at current index.
for(int i = 0; i <= end; i++)
{
// Stores count of consecutive 1s
int temp = (i == 1) ? (cntOne + 1) : 0;
// Update res.
res += cntN1X(str, len + 1, K, temp, dp,
(int)(KOne | ((temp == K) ? 1 : 0)),
(int)(tight & ((i == end) ? 1 : 0)));
}
return dp[len][cntOne][KOne][tight] = res;
}
// Function to count numbers in
// range[L, R] having K consecutive 1s.
public static int cntN1XL_R(int L, int R, int K)
{
// Stores binary representation
// of (L - 1)
String Ls = Integer.toBinaryString(L - 1);
// Stores binary representation
// of R
String Rs = Integer.toBinaryString(R);
// Stores values of overlapping
// subproblems
int dp[][][][] = new int[32][32][2][2];
// Initialize dp[][][][] array.
for(int i[][][] : dp)
for(int j[][] : i)
for(int k[] : j)
Arrays.fill(k, -1);
// Stores count of numbers from
// [1, L - 1] having K consecutive 1s
int resL = cntN1X(Ls, 0, K, 0, dp, 0, 1);
// Initialize dp[][][][] array.
for(int i[][][] : dp)
for(int j[][] : i)
for(int k[] : j)
Arrays.fill(k, -1);
// Stores count of numbers from
// [1, R - 1] having K consecutive 1s
int resR = cntN1X(Rs, 0, K, 0, dp, 0, 1);
// Return total counts having K
// consecutive 1s in range[L, R]
return (resR - resL);
}
// Driver Code
public static void main(String args[])
{
int L = 8;
int R = 100;
int K = 3;
System.out.println(cntN1XL_R(L, R, K));
}
}
// This code is contributed by hemanth gadarla
Python3
# Python3 program to implement
# the above approach
# Function to find the count of numbers in
# range[1, X] having K consecutive set bits
def cntN1X(stri, leng, K, cntOne, dp, KOne, tight):
# If length of current number is
# equal to length of string
if (leng == len(stri)):
# If count of consecutive set bits
# in the current string is >= K
return 1 if (KOne == 1) else 0;
# If already computedx
# equal occurred
if (dp[leng][cntOne][KOne][tight] != -1):
return dp[leng][cntOne][KOne][tight];
# If tight is 1, then element present
# at current index is element present
# in stri at current index. Otherwise, 1.
end = (ord(stri[leng]) - ord('0')) if tight == 1 else 1;
# Stores count of numbers whose
# leng th bit is i.
res = 0;
# Iterate over all possible
# value present at current index.
for i in range(end + 1):
# Stores count of consecutive 1s
temp = (cntOne + 1) if (i == 1) else 0;
# Update res.
res += cntN1X(stri, leng + 1,
K, temp, dp, 1 if(KOne | (temp == K)) else 0,
1 if(tight & (i == end)) else 0);
dp[leng][cntOne][KOne][tight]= res
return res
# Function to find
# binary representation of N
def convertBinary(N):
# Stores binary
# representation of N.
res=''
# Traverse each bit of N.
while(N != 0):
# Append current bit
# in res
res += chr((N % 2) + ord('0'));
# Update N.
N //= 2;
# Append 0 in binary representation
# Of N
while(len(res) < 32):
res += '0';
# Reverse binary representation of N
return res[::-1];
# Function to count numbers in
# range[L, R] having K consecutive 1s.
def cntN1XL_R(L, R, K):
# Stores binary representation
# of (L - 1)
Ls = str(convertBinary(L - 1));
# Stores binary representation
# of R
Rs = str(convertBinary(R));
# Stores values of overlapping
# subproblems
dp =[[[[-1,-1] for j in range(2)] for k in range(32)] for l in range(32)]
# Stores count of numbers from
# [1, L - 1] having K consecutive 1s
resL = cntN1X(Ls, 0, K, 0, dp, 0,1);
# Initialize dp[][][][] array.
dp = [[[[-1, -1] for j in range(2)] for k in range(32)] for l in range(32)]
# Stores count of numbers from
# [1, R - 1] having K consecutive 1s
resR = cntN1X(Rs, 0, K, 0,
dp, 0, 1);
# Return total counts having K
# consecutive 1s in range[L, R]
return (resR - resL);
# Driver Code
if __name__=='__main__':
L = 8;
R = 100;
K = 3;
print(cntN1XL_R(L, R, K))
# This code is contributed by rutvik_56
C#
// C# program to implement
// the above approach
using System;
class GFG{
// Function to find the count of numbers in
// range[1, X] having K consecutive set bits
public static int cntN1X(String str, int len, int K,
int cntOne, int [,,,]dp,
int KOne, int tight)
{
// If length of current number is
// equal to length of string
if (len == str.Length)
{
// If count of consecutive set bits
// in the current string is >= K
return (KOne == 1) ? 1 : 0;
}
// If already computedx
// equal occurred
if (dp[len, cntOne, KOne, tight] != -1)
{
return dp[len, cntOne, KOne, tight];
}
// If tight is 1, then element present
// at current index is element present
// in str at current index. Otherwise, 1.
int end = (tight == 1) ?
(str[len] - '0') : 1;
// Stores count of numbers whose
// len th bit is i.
int res = 0;
// Iterate over all possible
// value present at current index.
for(int i = 0; i <= end; i++)
{
// Stores count of consecutive 1s
int temp = (i == 1) ? (cntOne + 1) : 0;
// Update res.
res += cntN1X(str, len + 1, K, temp, dp,
(int)(KOne | ((temp == K) ? 1 : 0)),
(int)(tight & ((i == end) ? 1 : 0)));
}
return dp[len, cntOne, KOne, tight] = res;
}
// Function to count numbers in
// range[L, R] having K consecutive 1s.
public static int cntN1XL_R(int L, int R, int K)
{
// Stores binary representation
// of (L - 1)
String Ls = Convert.ToString(L - 1, 2);
// Stores binary representation
// of R
String Rs = Convert.ToString(R, 2);
// Stores values of overlapping
// subproblems
int [,,,]dp = new int[ 32, 32, 2, 2 ];
// Initialize [,]dp[,] array.
for(int i = 0; i < 32; i++)
for(int j = 0; j < 32; j++)
for(int k = 0; k < 2; k++)
for(int l = 0; l < 2; l++)
dp[i, j, k, l] = -1;
// Stores count of numbers from
// [1, L - 1] having K consecutive 1s
int resL = cntN1X(Ls, 0, K, 0, dp, 0, 1);
// Initialize [,]dp[,] array.
for(int i = 0; i < 32; i++)
for(int j = 0; j < 32; j++)
for(int k = 0; k < 2; k++)
for(int l = 0; l < 2; l++)
dp[i, j, k, l] = -1;
// Stores count of numbers from
// [1, R - 1] having K consecutive 1s
int resR = cntN1X(Rs, 0, K, 0, dp, 0, 1);
// Return total counts having K
// consecutive 1s in range[L, R]
return (resR - resL);
}
// Driver Code
public static void Main(String []args)
{
int L = 8;
int R = 100;
int K = 3;
Console.WriteLine(cntN1XL_R(L, R, K));
}
}
// This code is contributed by gauravrajput1
Javascript
27
时间复杂度: O(32 2 * 2 3 )
辅助空间: O(32 2 * 2 2 )
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。