在很多情况下,我们使用整数值作为数组中的索引来查看是否存在,我们可以使用位操作来优化此类问题中的空间。
让我们以下面的问题为例。
给定两个数字a和b,请使用小于O(| b – a |)的空间标记a和b之间2和5的倍数,并输出每个倍数。
注意:我们必须标记倍数,即在内存中保存(键,值)对,以使每个键的值分别为1或0,分别表示2或5的倍数。
例子 :
Input : 2 10
Output : 2 4 5 6 8 10
Input: 60 95
Output: 60 62 64 65 66 68 70 72 74 75 76 78
80 82 84 85 86 88 90 92 94 95
方法1(简单):
将索引从a散列到b并将每个索引标记为1或0。
空间复杂度:O(max(a,b))
方法2(优于简单):
通过将a转换为第0个索引并将b转换为第(ba)个索引来节省内存。
空间复杂度:O(| ba |)。
只需哈希| b – a |数组的位置为0和1。
C++
// C++ program to mark numbers as multiple of 2 or 5
#include
using namespace std;
// Driver code
int main()
{
int a = 2, b = 10;
int size = abs(b - a) + 1;
int* array = new int[size];
// Iterate through a to b, If it is a multiple
// of 2 or 5 Mark index in array as 1
for (int i = a; i <= b; i++)
if (i % 2 == 0 || i % 5 == 0)
array[i - a] = 1;
cout << "MULTIPLES of 2 and 5:\n";
for (int i = a; i <= b; i++)
if (array[i - a] == 1)
cout << i << " ";
return 0;
}
Java
// Java program to mark numbers as
// multiple of 2 or 5
import java.lang.*;
class GFG {
// Driver code
public static void main(String[] args)
{
int a = 2, b = 10;
int size = Math.abs(b - a) + 1;
int array[] = new int[size];
// Iterate through a to b, If
// it is a multiple of 2 or 5
// Mark index in array as 1
for (int i = a; i <= b; i++)
if (i % 2 == 0 || i % 5 == 0)
array[i - a] = 1;
System.out.println("MULTIPLES of 2"
+ " and 5:");
for (int i = a; i <= b; i++)
if (array[i - a] == 1)
System.out.printf(i + " ");
}
}
// This code is contributed by
// Smitha Dinesh Semwal
Python3
# Python 3 program to mark numbers
# as multiple of 2 or 5
import math
# Driver code
a = 2
b = 10
size = abs(b - a) + 1
array = [0] * size
# Iterate through a to b,
# If it is a multiple of 2
# or 5 Mark index in array as 1
for i in range(a, b + 1):
if (i % 2 == 0 or i % 5 == 0):
array[i - a] = 1
print("MULTIPLES of 2 and 5:")
for i in range(a, b + 1):
if (array[i - a] == 1):
print(i, end=" ")
# This code is contributed by
# Smitha Dinesh Semwal
C#
// C# program to mark numbers as
// multiple of 2 or 5
using System;
class GFG {
// Driver code
static public void Main ()
{
int a = 2, b = 10;
int size = Math.Abs(b - a) + 1;
int[] array = new int[size];
// Iterate through a to b, If
// it is a multiple of 2 or 5
// Mark index in array as 1
for (int i = a; i <= b; i++)
if (i % 2 == 0 || i % 5 == 0)
array[i - a] = 1;
Console.WriteLine("MULTIPLES of 2" +
" and 5:");
for (int i = a; i <= b; i++)
if (array[i - a] == 1)
Console.Write(i + " ");
}
}
// This code is contributed by Ajit.
PHP
Javascript
C++
// CPP code to for marking multiples
#include
using namespace std;
// index >> 5 corresponds to dividing index by 32
// index & 31 corresponds to modulo operation of
// index by 32
// Function to check value of bit position whether
// it is zero or one
bool checkbit(int array[], int index)
{
return array[index >> 5] & (1 << (index & 31));
}
// Sets value of bit for corresponding index
void setbit(int array[], int index)
{
array[index >> 5] |= (1 << (index & 31));
}
/* Driver program to test above functions*/
int main()
{
int a = 2, b = 10;
int size = abs(b - a);
// Size that will be used is actual_size/32
// ceil is used to initialize the array with
// positive number
size = ceil(size / 32);
// Array is dynamically initialized as
// we are calculating size at run time
int* array = new int[size];
// Iterate through every index from a to b and
// call setbit() if it is a multiple of 2 or 5
for (int i = a; i <= b; i++)
if (i % 2 == 0 || i % 5 == 0)
setbit(array, i - a);
cout << "MULTIPLES of 2 and 5:\n";
for (int i = a; i <= b; i++)
if (checkbit(array, i - a))
cout << i << " ";
return 0;
}
Java
// Java code to for marking multiples
import java.io.*;
import java.util.*;
class GFG
{
// index >> 5 corresponds to dividing index by 32
// index & 31 corresponds to modulo operation of
// index by 32
// Function to check value of bit position whether
// it is zero or one
static boolean checkbit(int array[], int index)
{
int val = array[index >> 5] & (1 << (index & 31));
if (val == 0)
return false;
return true;
}
// Sets value of bit for corresponding index
static void setbit(int array[], int index)
{
array[index >> 5] |= (1 << (index & 31));
}
// Driver code
public static void main(String args[])
{
int a = 2, b = 10;
int size = Math.abs(b-a);
// Size that will be used is actual_size/32
// ceil is used to initialize the array with
// positive number
size = (int)Math.ceil((double)size / 32);
// Array is dynamically initialized as
// we are calculating size at run time
int[] array = new int[size];
// Iterate through every index from a to b and
// call setbit() if it is a multiple of 2 or 5
for (int i = a; i <= b; i++)
if (i % 2 == 0 || i % 5 == 0)
setbit(array, i - a);
System.out.println("MULTIPLES of 2 and 5:");
for (int i = a; i <= b; i++)
if (checkbit(array, i - a))
System.out.print(i + " ");
}
}
// This code is contributed by rachana soma
C#
// C# code to for marking multiples
using System;
class GFG
{
// index >> 5 corresponds to dividing index by 32
// index & 31 corresponds to modulo operation of
// index by 32
// Function to check value of bit position
// whether it is zero or one
static bool checkbit(int []array, int index)
{
int val = array[index >> 5] &
(1 << (index & 31));
if (val == 0)
return false;
return true;
}
// Sets value of bit for corresponding index
static void setbit(int []array, int index)
{
array[index >> 5] |= (1 << (index & 31));
}
// Driver code
public static void Main(String []args)
{
int a = 2, b = 10;
int size = Math.Abs(b-a);
// Size that will be used is actual_size/32
// ceil is used to initialize the array with
// positive number
size = (int)Math.Ceiling((double)size / 32);
// Array is dynamically initialized as
// we are calculating size at run time
int[] array = new int[size];
// Iterate through every index from a to b and
// call setbit() if it is a multiple of 2 or 5
for (int i = a; i <= b; i++)
if (i % 2 == 0 || i % 5 == 0)
setbit(array, i - a);
Console.WriteLine("MULTIPLES of 2 and 5:");
for (int i = a; i <= b; i++)
if (checkbit(array, i - a))
Console.Write(i + " ");
}
}
// This code is contributed by 29AjayKumar
输出 :
MULTIPLES of 2 and 5:
2 4 5 6 8 10
方法3(使用位操作) :
这是一个优化的空间,它使用位操作技术,该技术可以应用于在数组中映射二进制值的问题。
在64位编译器中,int变量的大小为4个字节。 1个字节由内存中的8位位置表示。因此,内存中的一个整数由32位位置(4字节)表示,这32位位置可以被使用,而不是仅使用一个索引来哈希二进制值。
C++
// CPP code to for marking multiples
#include
using namespace std;
// index >> 5 corresponds to dividing index by 32
// index & 31 corresponds to modulo operation of
// index by 32
// Function to check value of bit position whether
// it is zero or one
bool checkbit(int array[], int index)
{
return array[index >> 5] & (1 << (index & 31));
}
// Sets value of bit for corresponding index
void setbit(int array[], int index)
{
array[index >> 5] |= (1 << (index & 31));
}
/* Driver program to test above functions*/
int main()
{
int a = 2, b = 10;
int size = abs(b - a);
// Size that will be used is actual_size/32
// ceil is used to initialize the array with
// positive number
size = ceil(size / 32);
// Array is dynamically initialized as
// we are calculating size at run time
int* array = new int[size];
// Iterate through every index from a to b and
// call setbit() if it is a multiple of 2 or 5
for (int i = a; i <= b; i++)
if (i % 2 == 0 || i % 5 == 0)
setbit(array, i - a);
cout << "MULTIPLES of 2 and 5:\n";
for (int i = a; i <= b; i++)
if (checkbit(array, i - a))
cout << i << " ";
return 0;
}
Java
// Java code to for marking multiples
import java.io.*;
import java.util.*;
class GFG
{
// index >> 5 corresponds to dividing index by 32
// index & 31 corresponds to modulo operation of
// index by 32
// Function to check value of bit position whether
// it is zero or one
static boolean checkbit(int array[], int index)
{
int val = array[index >> 5] & (1 << (index & 31));
if (val == 0)
return false;
return true;
}
// Sets value of bit for corresponding index
static void setbit(int array[], int index)
{
array[index >> 5] |= (1 << (index & 31));
}
// Driver code
public static void main(String args[])
{
int a = 2, b = 10;
int size = Math.abs(b-a);
// Size that will be used is actual_size/32
// ceil is used to initialize the array with
// positive number
size = (int)Math.ceil((double)size / 32);
// Array is dynamically initialized as
// we are calculating size at run time
int[] array = new int[size];
// Iterate through every index from a to b and
// call setbit() if it is a multiple of 2 or 5
for (int i = a; i <= b; i++)
if (i % 2 == 0 || i % 5 == 0)
setbit(array, i - a);
System.out.println("MULTIPLES of 2 and 5:");
for (int i = a; i <= b; i++)
if (checkbit(array, i - a))
System.out.print(i + " ");
}
}
// This code is contributed by rachana soma
C#
// C# code to for marking multiples
using System;
class GFG
{
// index >> 5 corresponds to dividing index by 32
// index & 31 corresponds to modulo operation of
// index by 32
// Function to check value of bit position
// whether it is zero or one
static bool checkbit(int []array, int index)
{
int val = array[index >> 5] &
(1 << (index & 31));
if (val == 0)
return false;
return true;
}
// Sets value of bit for corresponding index
static void setbit(int []array, int index)
{
array[index >> 5] |= (1 << (index & 31));
}
// Driver code
public static void Main(String []args)
{
int a = 2, b = 10;
int size = Math.Abs(b-a);
// Size that will be used is actual_size/32
// ceil is used to initialize the array with
// positive number
size = (int)Math.Ceiling((double)size / 32);
// Array is dynamically initialized as
// we are calculating size at run time
int[] array = new int[size];
// Iterate through every index from a to b and
// call setbit() if it is a multiple of 2 or 5
for (int i = a; i <= b; i++)
if (i % 2 == 0 || i % 5 == 0)
setbit(array, i - a);
Console.WriteLine("MULTIPLES of 2 and 5:");
for (int i = a; i <= b; i++)
if (checkbit(array, i - a))
Console.Write(i + " ");
}
}
// This code is contributed by 29AjayKumar
输出:
MULTIPLES of 2 and 5:
2 4 5 6 8 10