Sum of Hamming Distances - optimization

I started preparing for an interview and came across this problem:
An array of integers is given
Now calculate the sum of Hamming distances of all pairs of integers in the array in their binary representation.
Example:
given {1,2,3} or {001,010,011} (used 3 bits just to simplify)
result= HD(001,010)+HD(001,011)+HD(010,011)= 2+1+1=4;
The only optimization, from a purely brute force solution, I know I can use here, is in the individual calculation of Hamming Distance as seen here:
int hamming_distance(unsigned x, unsigned y)
{
int dist;
unsigned val;
dist = 0;
val = x ^ y; // XOR
// Count the number of bits set
while (val != 0)
{
// A bit is set, so increment the count and clear the bit
dist++;
val &= val - 1;
}
// Return the number of differing bits
return dist;
}
What's the best way to go about solving this problem?

Here is my C++ implementation, with O(n) complexity and O(1) space.
int sumOfHammingDistance(vector<unsigned>& nums) {
int n = sizeof(unsigned) * 8;
int len = nums.size();
vector<int> countOfOnes(n, 0);
for (int i = 0; i < len; i++) {
for (int j = 0; j < n; j++) {
countOfOnes[j] += (nums[i] >> j) & 1;
}
}
int sum = 0;
for (int count: countOfOnes) {
sum += count * (len - count);
}
return sum;
}

You can consider the bit-positions separately. That gives you 32 (or some other number) of easier problems, where you still have to calculate the sum of all pairs of hamming distances, except now it's over 1-bit numbers.
The hamming distance between two 1-bit numbers is their XOR.
And now it has become the easiest case of this problem - it's already split per bit.
So to reiterate the answer to that question, you take a bit position, count the number of 0's and the number of 1's, multiply those to get the contribution of this bit position. Sum those for all bit positions. It's even simpler than the linked problem, because the weight of the contribution of every bit is 1 in this problem.

Related

Binary search to solve 'Kth Smallest Element in a Sorted Matrix'. How can one ensure the correctness of the algorithm,

I'm referring to the leetcode question: Kth Smallest Element in a Sorted Matrix
There are two well-known solutions to the problem. One using Heap/PriorityQueue and other is using Binary Search. The Binary Search solution goes like this (top post):
public class Solution {
public int kthSmallest(int[][] matrix, int k) {
int lo = matrix[0][0], hi = matrix[matrix.length - 1][matrix[0].length - 1] + 1;//[lo, hi)
while(lo < hi) {
int mid = lo + (hi - lo) / 2;
int count = 0, j = matrix[0].length - 1;
for(int i = 0; i < matrix.length; i++) {
while(j >= 0 && matrix[i][j] > mid) j--;
count += (j + 1);
}
if(count < k) lo = mid + 1;
else hi = mid;
}
return lo;
}
}
While I understand how this works, I have trouble figuring out one issue.
How can we be sure that the returned lo is always in the matrix?
Since the search space is min and max value of the array, the mid need NOT be a value that is in the array. However, the returned lo always is.
Why is this happening?
For the sake of argument, we can move the calculation of count to a separate function like the following:
bool valid(int mid, int[][] matrix, int k) {
int count = 0, m = matrix.length;
for (int i = 0; i < m; i++) {
int j = 0;
while (j < m && matrix[i][j] <= mid) j++;
count += j;
}
return (count < k);
}
This predicate will do exactly same as your specified operation. Here, the loop invariant is that, the range [lo, hi] always contains the kth smallest number of the 2D array.
In other words, lo <= solution <= hi
Now, when the loop terminates, it is evident that lo >= hi
Merging those two properties, we get, lo = solution = hi, since solution is a member of array, it can be said that, lo is always in the array after loop termination and will rightly point to the kth smallest element.
Because We are finding the lower_bound using binary search and there cannot be any number smaller than the number(lo) in the array which could be the kth smallest element.

Selection sort implementation, I am stuck at calculating time complexity for number of swaps

static int count = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
swap(arr, i, j);
count++;
}
}
}
Is this the correct implementation for selection sort? I am not getting O(n-1) complexity for swaps with this implementation.
Is this the correct implementation for selection sort?
It depends, logically what you are doing is correct. It sort using "find the max/min value in the array". But, in Selection Sort, usually you didn't need more than one swap in one iteration. You just save the max/min value in the array, then at the end you swap it with the i-th element
I am not getting O(n-1) complexity for swaps
did you mean n-1 times of swap? yes, it happen because you swap every times find a larger value not only on the largest value. You can try to rewrite your code like this:
static int count=0;
static int maximum=0;
for(int i=0;i<arr.length-1;i++){
maximum = i;
for(int j=i+1;j<arr.length;j++){
if(arr[j] > arr[maximum]){
maximum = j;
}
}
swap(arr[maximum],arr[i]);
count++;
}
Also, if you want to exact n-1 times swap, your iteration for i should changed too.

Simulating a card game. degenerate suits

This might be a bit cryptic title but I have a very specific problem. First my current setup
Namely in my card simulator I deal 32 cards to 4 players in sets of 8. So 8 cards per player.
With the 4 standard suits (spades, harts , etc)
My current implementation cycles threw all combinations of 8 out of 32
witch gives me a large number of possibilities.
Namely the first player can have 10518300 different hands be dealt.
The second can then be dealt 735471 different hands.
The third player then 12870 different hands.
and finally the fourth can have only 1
giving me a grand total of 9.9561092e+16 different unique ways to deal a deck of 32 cards to 4 players. if the order of cards doesn’t matter.
On a 4 Ghz processor even with 1 tick per possibility it would take me half a year.
However I would like to simplify this dealing of cards by making the exchange of diamonds, harts and spades. Meaning that dealing of 8 harts to player 1 is equivalent to dealing 8 spades. (note that this doesn’t apply to clubs)
I am looking for a way to generate this. Because this will cut down the possibilities of the first hand by at least a factor of 6. My current implementation is in c++.
But feel free to answer in a different Languages
/** http://stackoverflow.com/a/9331125 */
unsigned cjasMain::nChoosek( unsigned n, unsigned k )
{
//assert(k < n);
if (k > n) return 0;
if (k * 2 > n) k = n-k;
if (k == 0) return 1;
int result = n;
for( int i = 2; i <= k; ++i ) {
result *= (n-i+1);
result /= i;
}
return result;
}
/** [combination c n p x]
* get the [x]th lexicographically ordered set of [r] elements in [n]
* output is in [c], and should be sizeof(int)*[r]
* http://stackoverflow.com/a/794 */
void cjasMain::Combination(int8_t* c,unsigned n,unsigned r, unsigned x){
++x;
assert(x>0);
int i,p,k = 0;
for(i=0;i<r-1;i++){
c[i] = (i != 0) ? c[i-1] : 0;
do {
c[i]++;
p = nChoosek(n-c[i],r-(i+1));
k = k + p;
} while(k < x);
k = k - p;
}
c[r-1] = c[r-2] + x - k;
}
/**http://stackoverflow.com/a/9430993 */
template <unsigned n,std::size_t r>
void cjasMain::Combinations()
{
static_assert(n>=r,"error n needs to be larger then r");
std::vector<bool> v(n);
std::fill(v.begin() + r, v.end(), true);
do
{
for (int i = 0; i < n; ++i)
{
if (!v[i])
{
COUT << (i+1) << " ";
}
}
static int j=0;
COUT <<'\t'<< j++<< "\n";
}
while (std::next_permutation(v.begin(), v.end()));
return;
}
A requirement is that from lexicographical number I can get back the original array.
Even the slightest optimization can help my monto carol simulation I hope.

Multiply 2 very big numbers in IOS

I have to multiply 2 large integer numbers, every one is 80+ digits.
What is the general approach for such kind of tasks?
You will have to use a large integer library. There are some open source ones listed on Wikipedia's Arbitrary Precision arithmetic page here
We forget how awesome it is that CPUs can multiply numbers that fit into a single register. Once you try to multiply two numbers that are bigger than a register you realize what a pain in the ass it is to actually multiply numbers.
I had to write a large number class awhile back. Here is the code for my multiply function. KxVector is just an array of 32 bit values with a count, and pretty self explanatory, and not included here. I removed all the other math functions for brevity. All the math operations are easy to implement except multiply and divide.
#define BIGNUM_NEGATIVE 0x80000000
class BigNum
{
public:
void mult( const BigNum& b );
KxVector<u32> mData;
s32 mFlags;
};
void BigNum::mult( const BigNum& b )
{
// special handling for multiply by zero
if ( b.isZero() )
{
mData.clear();
mFlags = 0;
return;
}
// apply sign
mFlags ^= b.mFlags & BIGNUM_NEGATIVE;
// multiply two numbers using a naive multiplication algorithm.
// this would be faster with karatsuba or FFT based multiplication
const BigNum* ppa;
const BigNum* ppb;
if ( mData.size() >= b.mData.size() )
{
ppa = this;
ppb = &b;
} else {
ppa = &b;
ppb = this;
}
assert( ppa->mData.size() >= ppb->mData.size() );
u32 aSize = ppa->mData.size();
u32 bSize = ppb->mData.size();
BigNum tmp;
for ( u32 i = 0; i < aSize + bSize; i++ )
tmp.mData.insert( 0 );
const u32* pb = ppb->mData.data();
u32 carry = 0;
for ( u32 i = 0; i < bSize; i++ )
{
u64 mult = *(pb++);
if ( mult )
{
carry = 0;
const u32* pa = ppa->mData.data();
u32* pd = tmp.mData.data() + i;
for ( u32 j = 0; j < aSize; j++ )
{
u64 prod = ( mult * *(pa++)) + *pd + carry;
*(pd++) = u32(prod);
carry = u32( prod >> 32 );
}
*pd = u32(carry);
}
}
// remove leading zeroes
while ( tmp.mData.size() && !tmp.mData.last() ) tmp.mData.pop();
mData.swap( tmp.mData );
}
It depends on what you want to do with the numbers. Do you want to use more arithmetic operators or do you simply want to multiply two numbers and then output them to a file? If it's the latter it's fairly simple to put the digits in an int or char array and then implement a multiplication function which works just like you learned to do multiplication by hands.
This is the simplest solution if you want to do this in C, but of course it's not very memory efficient. I suggest looking for Biginteger libraries for C++, e.g. if you want to do more, or just implement it by yourself to suit your needs.

Which are faster squares or roots?

for (int i = 2; i * i <= n; i++)
for (int i = 2; i <= SQRT(n); i++)
just wondering which is faster I looked at some primitive algorithms for getting roots and it would seem to me that squaring the number would be faster but I don't know for sure. These loops are for determining a numbers "primeness".
Shouldn't the comaprison be between
int sqrt = SQRT(n);
for (int i = 2; i <= sqrt; i++)
and
for (int i = 2; i * i <= n; i++)
The answer will depend on how many loop iterations you do. The sqrt method does less work per iteration, but it has a higher start-up cost. Mind you, this reeks of premature optimisation.
Compiler may 'cache' result of SQRT (n), but i * i it should compute on each step.
Square root will take longer, unless it's implemented in hardware, lookup, or a special machine code version. Newton iteration is the algorithm of choice; it converges quadratically.
Best to benchmark for yourself. I'd recommend moving the call to square root outside the loop so you only do it once rather than every time you check the exit condition.
Why not skip both of them and use some clever maths? The Following code avoid both of them using the Property that Sum of the First n odd numbers is always a perfect square.
A shameless plug for my old blogpost (from my dead blog)
int isPrime(int n)
{
int squares = 1;
int odd = 3;
if( ((n & 1) == 0) || (n < 9)) return (n == 2) || ((n > 1) && (n & 1));
else
{
for( ;squares <= n; odd += 2)
{
if( n % odd == 0)
return 0;
squares+=odd;
}
return 1;
}
}
The square will be faster.
But the square will overflow if n is larger than the square root of the largest int, and then the comparison will go wrong. The square root function could (and you would expect to) be implemented in such a way that is can be calculated on arguments all the way up to the largest representable int. That means it won't go wrong in that way.
In Java, the largest int is 2^31 - 1, which means its square root is just under 46341. If you want to look for primes larger than that, the squaring would stop you.