Google Interview Question
Computer ScientistsCountry: United States
Interview Type: In-Person
From Mathworld site:
" The formula for the concatenation of numbers p and q in base b is
p∥q=pb^(l(q))+q,
where
l(q)=|_log_bq_|+1 "
This is a solution in constant time..
Hi all. I see a lot of O(n) solutions but this problem can actually be solved in O(log n) time.
public int concatInts (int a, int b) {
return a * findMostSigDig(b, 10) + b;
}
/* Notice in this following method, I am not iterating through b linearly but exponentially therefore you get a log n solution */
public int findMostSigDig (int b, int prev, int pos) {
/* if pos is currently less than most significant digit */
if (b/pos > 0) {
return findMostSigDig(b, pos, pos*pos);
}
/* if pos is currently at one position greater than the most significant digit
if (b/(pos/10) > 0) {
return pos;
}
/* if we have overshot pos, recurse with smaller subset */
return findMostSigDig(b / prev, 1, 10) * prev;
}
This code has NOT been tested and can be full of bugs but this is the general idea. Solution may change depending on whether negatives are allowed or what the range of ints are.
Sorry the return statement for concatInts should actually be something like:
return a * findMostSigDig(b, 1, 10) + b;
Forgot a parameter in there. Can be initialized as 0 or 1 or even -1 but this value currently does not matter.
Last update. I went ahead and tested the code and it works. Once again the final solution is:
/* if pos is currently less than most significant digit */
if (b/pos > 0) {
return findMostSigDig(b, pos, pos*pos);
}
/* if pos is currently at one position greater than the most significant digit*/
if (b/(pos/10) > 0) {
return pos;
}
/* if we have overshot pos, recurse with smaller subset */
return findMostSigDig(b / prev, 1, 10) * prev;
The second number in your example is out of range of int type in java.
I assume that the result and numbers are in range of int type:
Code:
private static void concat(long a, long b) {
long temp = b;
while (temp > 0) {
temp /= 10;
a *= 10;
}
a += b;
System.out.println(a);
}
Time complexity O(m) - m number of digits in sec number.
It's completely possible for this to be a Google interview question. It could have been a warmup or screening question.
github.com/techpanja/interviewproblems/tree/master/src/numberproblems
public static void concatenateNumbers(long x, long y) {
long temp = y;
do {
temp = temp / 10;
x = x * 10;
} while (temp > 0);
System.out.println(x + y);
}
An response in Go
package main
import "fmt"
func main() {
b:= []int{1,1,2,2,2,3,3,4,5,7,15,15,15,15,15,17}
max_count := 1
count := 1
max_value := b[0]
for i:=1; i < len(b) ; i++ {
// We increment the count if the same value
if b[i-1] == b[i] {
count = count + 1
}
if b[i] != b[i-1] {
count = 1
}
if count > max_count {
max_count = count
max_value = b[i]
}
}
fmt.Println("Total value:", max_value, "appears",max_count,"times")
}
in Java. I don't know that much of complexities thing.
If anyone can provide me some good tutorials regarding algorithm complexities that will be a great help.
public static int concatInt(int x,int y)
{
int len=String.valueOf(x).length();
return((int)(x*(Math.pow(10,len))+y));
}
Time complexity depends on rank.
We can find rank using binary search because int has manixum number and minimun number. In this case, time complexity is log(rank(b))
int pow10(int n){ // Return value can be pre caluclated
return (int) Math.pow(10,(double) n);
}
int rank(int a, int left, int right){
if(right == left){
return right;
}
if(right > left){
return -1;
}
m = (right - left) / 2;
if( a < pow(10, m){
return rank(a, left, m);
}else{
return rank(a, m, right);
}
}
If we can restrict the arguments to positive integers (likely), this can be done very simply.
The trick is to use a logarithm:
public static int concat(int a, int b) {
return (int) (a * Math.pow(10, Math.ceil(Math.log10(b))) + b);
}
Not sure what the runtime is since I don't know a lot about how log10 and pow are implemented. I'd guess that it's logarithmic, or near-constant since we are just dealing with relatively small variations in the problem size.
Suppose we have two integer
int i1 = 9890780787890
int i2 = 8908908
Size of integer in Java is 4 bytes.
The standard Java integer data types are:
byte 1 byte -128 to 127
short 2 bytes -32,768 to 32,767
int 4 bytes -2,147,483,648 to 2,147,483,647 (- 2.14 Billion and -2.14 Billion)
long 8 bytes -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
How can concatenate these two.
Approach 1
Simple, No big deal .. one way is use String and sum this two.
Mean time is
Mean: 052
Approach 2
Multiplying the first one with 10X where X is number of zeros and sum.
Mean with this approach is
Mean 1490
import java.util.Random;
import java.util.Timer;
public class FastestIntConcatenation {
private static Timer timer ;
private static long mean;
private static int iterationCnt=1;
private static long timeCalculator(int i1, int i2, int approachFlag)
{
long startTime = System.nanoTime();
if(approachFlag == 1) approach1(i1, i2);
if(approachFlag == 2) approach2(i1, i2);
//if(approachFlag == 3) approach3(i1, i2);
long endTime = System.nanoTime();
long diff = endTime - startTime;
mean = (mean * iterationCnt + diff) /(iterationCnt + 1);
iterationCnt = iterationCnt + 1;
//System.out.println(("Diff:" + diff + ", mean:" + mean));
return mean;
}
private static String approach1(int i1, int i2)
{
return i1 + "" + i2;
}
private static void approach2(int a, int b)
{
long temp = b;
while (temp > 0) {
temp /= 10;
a *= 10;
}
a += b;
//System.out.println(a);
}
public static void main(String[] args) {
timer = new Timer();
int i1 = 23232;
int i2 = 1313213;
Random r = new Random();
//approach2(i1, i2);
for (int i = 0; i < 1000; i++) { i1 = r.nextInt(); i2 = r.nextInt();
System.out.println("Mean 0" + timeCalculator(i1, i2,0)); }
System.out.println("Approach 2 Starts");
for (int i = 0; i < 1000; i++) { i1 = r.nextInt(); i2 = r.nextInt();
System.out.println("Mean 1" + timeCalculator(i1, i2,1)); }
}
}
concat(n1,n2)
// Assuming there is no buffer overflow
1. x = number of digits in n2, i:e ceil(log to the base 10 of n2)
2. if(x ==0 ) x = 1;
3. return n1*x +n2
- hmm December 30, 2013