Given a long number n, we need to return a long number which we get from the concatenation of binary representation from 1 to n?
Example say n=3, then answer would be 27, as 1 in binary is 01, 2 is 10 and 3 is 11 so concatenation would be 011011 which is 27.
this is the approach I used,
class Solution {
static String[] arr;
public static long binaryArray(long A) {
String res = "";
for (long i = 1; i <= A; i++) {
res += toBinary(i);
}
long rest = toLong(res);
return rest % 1000000007;
}
static long toLong(String s) {
int a = s.length();
int pow = 0;
long res = 0;
for (int i = a - 1; i >= 0; i--) {
char aa = s.charAt(i);
long f = Character.getNumericValue(aa);
long power = (long) Math.pow(2, pow);
res += power * f;
pow++;
}
return res;
}
static String toBinary(long a) {
if (a == 0) {
return "0";
}
String binary = "";
binary = Long.toBinaryString(a);
return binary;
}
public static void main(String args[]) {
long n = 89900;
arr = new String[(int) n + 1];
arr[0] = "0";
long startTime = System.nanoTime();
long b = binaryArray(n);
long endTime = System.nanoTime();
long totalTime = endTime - startTime;
long convert = TimeUnit.SECONDS.convert(totalTime, TimeUnit.NANOSECONDS);
System.out.println(convert);
System.out.println(b);
}
}
but it is not completing the request in the required time.
Is there a quicker way?
public static long f(int n) {
long n2 = ((long)n) << n;
return n2 | n;
}
There is much irrelevant text in the specification: binary representation, concatenation and such. What is said:
the bits of n should be "concatenated" n bits to the left = bit shift.
So this interview question was intentionally misleading, and the actual solution simple. It tried and succeeded to let the interviewee start with bit tests and such.
Now I am somewhat experienced and the trick is always to look at the whole picture,
think in notions like sets, or Integer's bit functions.
As #kaya3 commented, the following might be more correct.
public static long f(int n) {
long n2 = 0;
for (int i = 0; i < n; ++i) {
if ((n & (1 << i)) == 1) { // i'th bit set?
int bits = 32 - Integer.numberOfLeadingZeros(i);
n2 <<= bits;
n2 |= i;
}
}
return n2;
}
Related
I have constructed two ways to check palindrome of a number. Which one is more efficient? By efficiency, I mean in terms of execution time and memory allocations.
First, I convert an Integer to string and check if it is a palindrome. The example of code is as follow.
public class Palindrome{
/*
Function palindromeCheck
Return type boolean
Parameters characterArray
Checks character array for palindrome
*/
public static boolean palindromeCheck(char[] palinCheck){
boolean palindrome = true;
int firstLen = 0;
int secondLen = palinCheck.length - 1;
while(palindrome == true && firstLen < secondLen ){
if(palinCheck[firstLen] != palinCheck[secondLen]){
palindrome = false;
}
else{
firstLen++;
secondLen--;
}
} //end of while
return palindrome;
}
/*Main Function
Calls palinDromeCheck function
Prints results
*/
public static void main(String[] args){
int palinCheck = 1221;
String dipendra = Integer.toString(palinCheck);
char[] dipendraChar = dipendra.toCharArray();
System.out.println(palindromeCheck(dipendraChar));
}
}
The second method is without converting it to string.
public class PalindromeNumber{
/*
Function: PalindromeCheck
parameters integer
ReturnType: boolean
Takes integer, checks if it is palindrome and returns accordingly
*/
public static boolean palindromeCheck(int number){
int firstNumber = number;
int secondNumber = 0;
while(number >= 1){
secondNumber = secondNumber* 10 + (number%10);
number = number/10;
}
return (firstNumber==secondNumber) ? true:false;
}
public static void main(String[] args){
System.out.println(palindromeCheck(111));
}
}
I bet the second algorithm would be faster, and obviously more space efficient. If you assume n be the number of digits of the input number, in the first algorithm:
Integer.toString requires n steps to convert it to String.
palindromeCheck requires n / 2 comparisons to check whether it's a palindrome.
But, the second algorithm would require n steps to compute the reverse number (involving only integer operations) and only 1 comparison to check.
Let's try.
On the following example (with one specific number, on my specific machine...) :
580 ms - Your first solution
323 ms - Your second solution
1045 ms - BrentR's solution
Note I modified the code a bit (but not the logic). You should also take care of spaces and indentation.
public class Palindrome {
public static boolean isPalindrome1(int n) {
char a[] = Integer.toString(n).toCharArray();
int i = 0;
int j = a.length - 1;
while (i < j) {
if (a[i++] != a[j--]) return false;
}
return true;
}
public static boolean isPalindrome2(int n) {
int p = n, q = 0;
while (n > 0) {
q = 10 * q + n % 10;
n /= 10;
}
return p == q;
}
public static boolean isPalindrome3(int n) {
String s = Integer.toString(n);
return s.equalsIgnoreCase(new StringBuilder(s).reverse().toString());
}
public static void main(String[] args) {
final int m = 10000000;
long t1, t2;
boolean q;
t1 = System.currentTimeMillis();
for (int n = 0; n < m; n++) {
q = isPalindrome1(123454321);
}
t2 = System.currentTimeMillis();
System.out.println(t2 - t1);
t1 = System.currentTimeMillis();
for (int n = 0; n < m; n++) {
q = isPalindrome2(123454321);
}
t2 = System.currentTimeMillis();
System.out.println(t2 - t1);
t1 = System.currentTimeMillis();
for (int n = 0; n < m; n++) {
q = isPalindrome3(123454321);
}
t2 = System.currentTimeMillis();
System.out.println(t2 - t1);
}
}
Why are you re-inventing the wheel?
java.lang.StringBuilder already provides a string reverse method
String string = Integer.toString(10101);
boolean palindrome = string.equalsIgnoreCase(new StringBuilder(string).reverse().toString());
I used method a that counts the amount of possible choices for getting like number 10 with numbers that are from 0 to 6. Problem is that it just takes too much time when x is like 50 or something. I just need some tips what I should do to make this faster.
Code
public static int count(int x) {
if (x < 0) {
return 0;
}
if (x == 0) {
return 1;
}
int result = 0;
for (int i = 1; i <= 6; i++) {
result += count(x - i);
}
return result;
}
This is a variation on Fibonacci except it is the sum of the last six values instead.
You can use a plain loop which will be faster than memorisation (the first time)
public static long count(int x) {
long a=0, b=0, c=0, d=0, e=0, f=1;
while(x-- > 0) {
long sum = a + b + c + d + e + f;
a = b; b = c; c = d; d = e; e = f;
f = sum;
}
return f;
}
If you call this repeatedly you may as well store all the values in the int range which is likely to be less than 30 the first time and retrieve these values after that.
The question here would be to get the sum of powers (m^0 + m^1 + m^2 + m^3.... + m^n) using only FOR loops. Meaning, not using any other loops as well as Math.pow();
Is it even possible? So far, I am only able to work around getting m^n, but not the rest.
public static void main(String[] args){
Scanner scn = new Scanner(System.in);
int total = 1;
System.out.print("Enter value of m: ");
int m = scn.nextInt();
System.out.print("Enter value of n: ");
int n = scn.nextInt();
for (int i = 1; i <= n; i++){
total * m;
}
System.out.print(total);
}
Let's say m =8; and n = 4;
i gives me '1,2,3,4' which is what I need, but I am unable to power m ^ i.
Would be nice if someone could guide me into how it could be done, can't seem to progress onwards as I have limited knowledge in Java.
Thanks in advance!
You might want to rewrite it like this :
m^0 + m^1 + m^2 + m^3.... + m^n = 1 + m * (1 + m * (1 + m * (.... ) ) )
And you do it in a single for loop.
This should do the job (see explanations in comments):
public long count(long m, int pow) {
long result = 1;
for(int i = 0;i<pow; i++) {
result*=m +1;
}
return result;
}
You can nest loops. Use one to compute the powers and another to sum them.
You can do below:
int mul = 1;
total = 1;
for(int i=1;i<=n;i++) {
mul *= m;
total += mul;
}
System.out.println(total);
You can use a single loop which is O(N) instead of nested loops which is O(N^2)
long total = 1, power = m
for (int i = 1; i <= n; i++){
total += power;
power *= m;
}
System.out.print(total);
You can also use the formula for geometric series:
Sum[i = k..k+n](a^i) = (a^k - a^(k+n+1)) / (1 - a)
= a^k * (1 - a^(n+1)) / (1 - a)
With this, the implementation can be done in a single for loop (or 2 simple for loop): either with O(n) simple looping, or with O(log n) exponentiation by squaring.
However, the drawback is that the data type must be able to hold at least (1 - a^(n+1)), while summing up normally only requires the result to fit in the data type.
This is the solution :
for(int i=0;i<n;i++){
temp=1;
for(int j=0;j<=i;j++){
temp *= m;
}
total += temp;
}
System.out.println(total+1);
You can easily calculate powers using your own pow function, something like:
private static long power(int a, int b) {
if (b < 0) {
throw new UnsupportedOperationException("Negative powers not supported.");
}
if (b == 0) {
return 1;
}
if (b == 1) {
return a;
}
return a * power(a, b - 1);
}
Then simply loop over all the values and add them up:
long out = 0;
for (int i = 0; i <= n; ++i) {
out += power(m, i);
}
System.out.println(out);
I would add that this is a classic dynamic programming problem as m^n is m * m^(n-1). I would therefore add caching of previously calculated powers so that you don't have to recalculate.
private static Map<Integer, Long> powers;
public static void main(String args[]) {
int m = 4;
int n = 4;
powers = new HashMap<>();
long out = 0;
for (int i = 0; i <= n; ++i) {
out += power(m, i);
}
System.out.println(out);
System.out.println(powers);
}
private static long power(int a, int b) {
if (b < 0) {
throw new UnsupportedOperationException("Negative powers not supported.");
}
if (b == 0) {
return 1;
}
if (b == 1) {
return a;
}
Long power = powers.get(b);
if (power == null) {
power = a * power(a, b - 1);
powers.put(b, power);
}
return power;
}
This caches calculated values so that you only calculate the next multiple each time.
Alright I am trying to solve a challenge one of my friends gave me to do, well I've manged to cut the last 9 digits out of a BigInteger well I had a way to cut-off the first 9 but it was so slow, it was taking too long.
The reason I need the first 9 and the last 9 is because I am looking for a BigInteger where the first and last are pandigital.
If you do not understand what I mean say we have n = new BigInteger("123456789987654321") well I need to get the "123456789" and the "987654321" seperately, and I do NOT want to convert the BigInteger to a string because that's a VERY slow process.
I am going for speed here, I am just stumped on this solution. I've heard something about using the Golden Ratio? Here is my code if you're interested.
import java.math.BigInteger;
public class Main {
public static void main(String...strings)
{
long timeStart = System.currentTimeMillis();
fib(350_000);
long timeEnd = System.currentTimeMillis();
System.out.println("Finished processing, time: " + (timeEnd - timeStart) + " milliseconds.");
}
public static BigInteger fib(int n)
{
BigInteger prev1 = BigInteger.valueOf(0), prev2 = BigInteger.valueOf(1);
for (int i = 0; i < n; i++)
{
// TODO: Check if the head is pandigital as well.
BigInteger tailing9Digits = tailing9Digits(prev1);
boolean tailPandigital = isPanDigital(tailing9Digits);
if (tailPandigital)
{
System.out.println("Solved at index: " + i);
break;
}
BigInteger savePrev1 = prev1;
prev1 = prev2;
prev2 = savePrev1.add(prev2);
}
return prev1;
}
public static BigInteger leading9Digits(BigInteger x)
{
// STUCK HERE.
return null;
}
public static BigInteger tailing9Digits(BigInteger x)
{
return x.remainder(BigInteger.TEN.pow(9));
}
static BigInteger[] pows = new BigInteger[16];
static
{
for (int i = 0; i < 16; i++)
{
pows[i] = BigInteger.TEN.pow(i);
}
}
static boolean isPanDigital(BigInteger n)
{
if (!n.remainder(BigInteger.valueOf(9)).equals(BigInteger.ZERO))
{
return false;
}
boolean[] foundDigits = new boolean[9];
boolean isPanDigital = true;
for (int i = 1; i <= 9; i++)
{
BigInteger digit = n.remainder(pows[i]).divide(pows[i - 1]);
for (int j = 0; j < foundDigits.length; j++) {
if (digit.equals(BigInteger.valueOf(j + 1)) && !foundDigits[j])
{
foundDigits[j] = true;
}
}
}
for (int i = 0; i < 9; i++)
{
isPanDigital = isPanDigital && foundDigits[i];
}
return isPanDigital;
}
}
BigInteger isn't something I'd recommend using if you care at all about speed. Most of its methods are poorly-implemented, and this typically results in very slow code.
There's a divide-and-conquer trick for division and radix conversion that you might find helpful.
First, BigInteger's multiply() is quadratic. You'll need to work around that, otherwise these divide-and-conquer tricks won't lead to any speedup. Multiplication via the fast Fourier transform is reasonably fast and good.
If you want to convert a BigInteger to base 10, break it in half (bitwise) and write it as a * 256^k + b. One thing you can do is convert a and b to base-10 recursively, then convert 256^k to decimal by repeated squaring, and then, in base 10, multiply a by 256^k and add b to the result. Also, since you're only interested in the first few digits, you might not even need to convert b if the first few digits of a * 256^k can't possibly be influenced by adding something as small as b.
A similar trick works for division.
You can do bit-shifting and extraction using the toByteArray() method.
Well I believe this is what you need:
import java.math.BigInteger;
public class PandigitalCheck {
public static void main(String[] args) {
BigInteger num = new BigInteger("12345678907438297438924239987654321");
long timeStart = System.currentTimeMillis();
System.out.println("Is Pandigital: " + isPandigital(num));
long timeEnd = System.currentTimeMillis();
System.out.println("Time Taken: " + (timeEnd - timeStart) + " ms");
}
private static boolean isPandigital(BigInteger num) {
if (getTrailing9Digits(num).compareTo(getLeading9Digits(num)) == 0) {
return true;
}
return false;
}
private static BigInteger getLeading9Digits(BigInteger num) {
int length = getBigIntLength(num);
BigInteger leading9 = BigInteger.ZERO;
for (int i = 0; i < 9; i++) {
BigInteger remainder = num.divide(BigInteger.TEN.pow(length - 1 - i));
leading9 = leading9.add(remainder.multiply(BigInteger.TEN.pow(i)));
num = num.remainder(BigInteger.TEN.pow(length - 1 - i));
}
return leading9;
}
private static int getBigIntLength(BigInteger num) {
for (int i = 1; ; i++) {
if (num.divide(BigInteger.TEN.pow(i)) == BigInteger.ZERO) {
return i;
}
}
}
private static BigInteger getTrailing9Digits(BigInteger num) {
return num.remainder(BigInteger.TEN.pow(9));
}
}
The output is:
Is Pandigital: true
Time Taken: 0 ms
Does it fit the bill?
I’m newbie for java, I’m converting BigInteger to String only but it's little bit fast as your code
import java.math.BigInteger;
public class Main {
public static void main(String args[])
{
long timeStart = System.currentTimeMillis();
String biStr = new BigInteger("123456789987654321").toString();
int length=(biStr.length())/2;
String[] ints = new String[length];
String[] ints2 = new String[length];
for(int i=0; i<length; i++) {
int j=i+length;
ints[i] = String.valueOf(biStr.charAt(i));
ints2[i] = String.valueOf(biStr.charAt(j));
System.out.println(ints[i] +" | "+ints2[i]);
}
long timeEnd = System.currentTimeMillis();
System.out.println("Finished processing, time: " + (timeEnd - timeStart) + " milliseconds.");
}
}
Maybe this is not too fast but at least it's simple
BigInteger n = new BigInteger("123456789987654321");
BigInteger n2 = n.divide(BigInteger.TEN.pow(new BigDecimal(n).precision() - 9));
BigInteger n1 = n.remainder(new BigInteger("1000000000"));
System.out.println(n1);
System.out.println(n2);
output
987654321
123456789
How to deal with a big hashcode value in rolling hash Rabin-Karp algorithm ? I use modular arithmetic to avoid negative number, however there is a problem when the hashcode exceeds my modulo number (N = 83559671). I set my base number to be prime (the number to calculate hashcode) as well as the modulo number (really big), but it doesn't work with long string. Can anyone see the problem?
Here is my code.
public static void main(String [] args){
int P = 13; // base
long M = 83559671;
long iHash = 0;
String word = "abcbadccaaaabbbb";
int WINDOW = 9;
for(int i = 0; i < WINDOW; i++){
iHash = int_mod(int_mod(iHash*P, M) + word[i], M);
}
for(int i = WINDOW; i < word.length; i++){
iHash = int_mod(iHash - word[i-WINDOW] * get_pow(P, WINDOW-1, M), M);
iHash = int_mod(iHash * P, M);
iHash = int_mod(iHash + word[i], M);
}
}
public static long get_pow(int p, int t, long M){
long a = 1;
for(int i = 0 ; i < t; i++){
a = int_mod(a * p, M);
}
return a;
}
public static long int_mod(long a, long b){
return (a % b+ b) % b;
}
The problem is when I have any string's length longer than 8 then the hashcode of the string exceeds the modulo number 83559671, and that leads to a wrong answer when I make a comparison. Any shorter strings work properly.
You don't need to do the modulus at all. Here's a demo:
public class Foo {
private static int hash(String s) {
int hash = 0;
for (int i = 0; i < s.length(); i++) {
hash *= 31;
hash += s.charAt(i);
}
return hash;
}
public static void main(String[] args) {
String s1 = "abcdefghij";
String s2 = s1.substring(1) + "k";
int pow = 1;
for (int i = 0; i < s1.length(); i++) {
pow *= 31;
}
System.out.printf("hash(%s) = %d%n", s1, hash(s1));
System.out.printf("hash(%s) = %d%n31 * hash(%s) - (31^%d * %s) + %s = %s%n",
s2,
hash(s2),
s1,
s1.length(),
s1.charAt(0),
s2.charAt(s2.length() - 1),
31 * hash(s1) - (pow * s1.charAt(0)) + s2.charAt(s2.length() - 1));
}
}
This (correctly) prints out:
hash(abcdefghij) = -634317659
hash(bcdefghijk) = 21611845
31 * hash(abcdefghij) - (31^10 * a) + k = 21611845
Why don't you treat your string as a polynomial? Suppose you have a string S of length n. Now take a look at the following function: F(x) = S[0]*x^(n-1) + S[1]*x^(n-2) + ... + S[i]*x^(n-i-1) + ... + S[n - 2]*x + S[n-1]. What happens if you try to compute F(P), where P is a base from your code snippet? Well, you'd get exactly the Rabin-Karp hash of string S. But since F(x) is a polynomial, we can use Horner's rule to compute the F(P). The resulting value might be very big, hence we use modular arithmetic:
static final long M = 83559671;
static final int Base = 13;
static long hash(String s, int from, int to) {
int iHash = 0;
for(int i = from; i < to; i++) {
iHash *= Base;
iHash += s.charAt(i);
iHash %= M;
}
return iHash;
}
You can use this function to obtain the hash of a string to be found in a text. And for initial window in the text. Then you can shift window and recalculate hash:
static void find(String pattern, String text) {
if(text.length() < pattern.length()) return;
int len = pattern.length();
long ph = hash(pattern, 0, len);
long h = hash(text, 0, len);
long basePower = mpow(Base, len);
if(h == ph) System.out.println("match at 0");
for(int i = len; i < text.length(); i++) {
h *= Base;
h += text.charAt(i);
h -= basePower * text.charAt(i - len);
h = mod(h);
if(h == ph) System.out.println("match at " + (i - len + 1));
}
}
static long mod(long a) {
a %= M;
if(a < 0) {
a += M;
}
return a;
}
static long mpow(long x, int k) {
long result = 1;
for(; k > 0; k >>= 1) {
if(k % 2 == 1) {
result = mod(result * x);
}
x = mod(x * x);
}
return result;
}
public static void main(String[] args) {
find("abracadabra", "abracadabracadabra");
}
For more information on this approach I recommend to refer to CLRS.