查找给定数组中的所有子数组索引范围,设置位和等于 X
给定一个长度为N的数组arr (从 1 开始的索引)和一个整数X ,任务是查找并打印数组中所有设置位和等于X的索引范围。
例子:
Input: A[] = {1 4 3 5 7}, X = 4
Output: (1, 3), (3, 4)
Explanation: In the above array subarray having set bit sum equal to X (= 4).
Starting from index 1 to 3. {1 4 3} = (001) + (100) + (011) = 4 and
other one is from 3 to 4 {3, 5} = (011) + (101) = 4.
Input: arr[] = {5, 3, 0, 4, 10}, X = 7
Output: (1 5)
Explanation: In the above array subarrays having set bit sum equal to X(= 7) start from 1 to 5 only.
方法:使用两个指针方法解决问题。
- 编写一个函数countSetBit 来计算设置的位数。
- 初始化计数器 c=0,以存储数组中每个数字的单独计数。
- 遍历数组并检查每个设置位并增加计数器。
- 用一组设置位的计数替换每个数字
- 编写一个函数来打印一系列子数组 PrintIndex
使用两个指针 i 和 j 运行循环并检查总和,如下所示:- 如果当前索引总和小于 X,则将 arr[j] 处的值添加到 currsum
- 否则,如果总和等于 X,则推回数组的开始和结束索引并增加计数器 i。
- 否则递减计数器,从 currsum 中减去 arr[i] 处的值。
- 对所有元素重复相同的操作。
下面是上述方法的实现:
C++
// C++ program to Find all range
// Having set bit sum X in array
#include
using namespace std;
// Function to replace elements
// With their set bit count
void countSetBit(vector& arr, int n)
{
int c = 0, i;
for (i = 0; i < n; i++) {
int x = arr[i];
while (x) {
int l = x % 10;
if (x & 1)
c++;
x /= 2;
}
// Replace array element
// to set bit count
arr[i] = c;
c = 0;
}
}
// Function to find range of subarrays
// having set bit sum equal to X.
void PrintIndex(vector arr, int N, int X,
vector& v)
{
int i = 0, j = 0, currSum = arr[0];
while (j < N && i < N) {
if (currSum == X) {
// push back index i start
// point ans end point j
// when sum == X
v.push_back(i + 1);
v.push_back(j + 1);
j++;
currSum += arr[j];
}
// when current sum is
// less than X increment j
// and add arr[j]
else if (currSum < X) {
j++;
currSum += arr[j];
}
// when current sum is
// greater than X increment j
// and subtract arr[i]
else {
currSum -= arr[i];
i++;
}
}
}
// Driver code
int main()
{
vector v = { 1, 4, 3, 5, 7 };
int X = 4;
int N = v.size();
// replace all the array element into
// their set bit count value
countSetBit(v, N);
vector ans;
PrintIndex(v, N, X, ans);
for (int i = 0; i < ans.size() - 1; i += 2)
cout << "(" << ans[i] << " "
<< ans[i + 1] << ")"
<< " ";
return 0;
}
Java
// JAVA code to implement the above approach
import java.util.*;
class GFG {
// Function to replace elements
// With their set bit count
static void countSetBit(int[] arr, int n)
{
int c = 0, i;
for (i = 0; i < n; i++) {
int x = arr[i];
while (x > 0) {
int l = x % 10;
if ((x & 1) == 1)
c++;
x /= 2;
}
// Replace array element
// to set bit count
arr[i] = c;
c = 0;
}
}
// Function to find range of subarrays
// having set bit sum equal to X.
static void PrintIndex(int[] arr, int N, int X,
ArrayList v)
{
int i = 0, j = 0, currSum = arr[0];
while (j < N && i < N) {
if (currSum == X) {
// push back index i start
// point ans end point j
// when sum == X
v.add(i + 1);
v.add(j + 1);
j++;
if (j < N)
currSum += arr[j];
}
// when current sum is
// less than X increment j
// and add arr[j]
else if (currSum < X) {
j++;
if (j < N)
currSum += arr[j];
}
// when current sum is
// greater than X increment j
// and subtract arr[i]
else {
currSum -= arr[i];
i++;
}
}
}
// Driver Code
public static void main(String[] args)
{
int[] v = { 1, 4, 3, 5, 7 };
int X = 4;
int N = v.length;
// replace all the array element into
// their set bit count value
countSetBit(v, N);
ArrayList ans = new ArrayList();
PrintIndex(v, N, X, ans);
for (int i = 0; i < ans.size() - 1; i += 2)
System.out.print("(" + ans.get(i) + " " + ans.get(i + 1)
+ ")"
+ " ");
}
}
// This code is contributed by sanjoy_62.
C#
// C# program to Find all range
// Having set bit sum X in array
using System;
using System.Collections;
class GFG {
// Function to replace elements
// With their set bit count
static void countSetBit(int[] arr, int n)
{
int c = 0, i;
for (i = 0; i < n; i++) {
int x = arr[i];
while (x > 0) {
int l = x % 10;
if ((x & 1) == 1)
c++;
x /= 2;
}
// Replace array element
// to set bit count
arr[i] = c;
c = 0;
}
}
// Function to find range of subarrays
// having set bit sum equal to X.
static void PrintIndex(int[] arr, int N, int X,
ArrayList v)
{
int i = 0, j = 0, currSum = arr[0];
while (j < N && i < N) {
if (currSum == X) {
// push back index i start
// point ans end point j
// when sum == X
v.Add(i + 1);
v.Add(j + 1);
j++;
if (j < N)
currSum += arr[j];
}
// when current sum is
// less than X increment j
// and add arr[j]
else if (currSum < X) {
j++;
if (j < N)
currSum += arr[j];
}
// when current sum is
// greater than X increment j
// and subtract arr[i]
else {
currSum -= arr[i];
i++;
}
}
}
// Driver code
public static void Main()
{
int[] v = { 1, 4, 3, 5, 7 };
int X = 4;
int N = v.Length;
// replace all the array element into
// their set bit count value
countSetBit(v, N);
ArrayList ans = new ArrayList();
PrintIndex(v, N, X, ans);
for (int i = 0; i < ans.Count - 1; i += 2)
Console.Write("(" + ans[i] + " " + ans[i + 1]
+ ")"
+ " ");
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
输出:
(1 3) (3 4)
时间复杂度: O(N * d) 其中 d 是数组元素中的位数
辅助空间: O(N)