Java - Recursion - Counting all combinations - java

i had a question regarding counting all possible combinations. For example if i have a recursive method that gives me an output of:
a. 0 0
b. 0 1
c. 1 0
d. 1 1
in this case i have 8 possible outputs. how should i count them using java?
i tried to use a counter but its giving me 4.
Please help.
Thanks.
here is my code.
public static void printAllAssignments(char set[], int k) {
int n = set.length;
printAllAssignments(set, "", n, k);
}
// The main recursive method to print all possible strings of length k
public static void printAllAssignments(char set[], String prefix, int n, int k) {
// Base case: k is 0, print prefix
if (k == 0) {
counterTotalAssignments++;
System.out.println("Occupancies: " + prefix);
return;
}
// One by one add all characters from set and recursively
// call for k equals to k-1
for (int i = 0; i < n; ++i) {
// Next character of input added
String newPrefix = prefix + set[i];
// k is decreased, because we have added a new character
printAllAssignments(set, newPrefix, n, k - 1);
}
}
public static void main(String[] args) {
char charSet[] = {'0', '1'};
int k = 2;
printAllAssignments(charSet, k);
System.out.println("Total number of assignments: " + counterTotalAssignments);
}
output:
Occupancies: 00
Occupancies: 01
Occupancies: 10
Occupancies: 11
Total number of assignments: 4

There's no reason to count them, when they can be calculated from your input:
combinations = exp (possible values per digit, number of digits)
If you insist on counting them I'd use the in your case unused return value:
Have the base case return 1 and return the sum of the return values of the recursive calls in the recursive case.
I just noticed that your counter is giving you the correct value. Why were you expecting it to be 8?
00 // 1.
01 // 2.
10 // 3.
11 // 4.

Related

I'm trying to convert a binary number to a decimal number but my Output is always 0

Here is my code. I tried to Convert the binary to a Char array, then multiply each char in the array by 2 to the power of its corresponding number in the array, then sum up all the values of the char array into a double. New to programming so a bit confused. My input Binary is txfBinaryInput, and my output label is lblDisplay.
private void btnProcessActionPerformed(java.awt.event.ActionEvent evt)
{
if (txfBinaryInput.getText().equals(""))
{
lblDisplay.setText("ERROR: NO INPUT");
} else
{
int n = 0;
int[] binaryValueStorage = new int[100];
double[] decimalValueStorage = new double[100];
String binaryInput = txfBinaryInput.getText();
int binaryNumber = binaryInput.length();
char[] binaryDigits = binaryInput.toCharArray();
for (int i = 0; i >= binaryNumber; i++)
{
binaryValueStorage[n] = binaryDigits[n];
decimalValueStorage[n] = binaryValueStorage[n] * (Math.pow(2, n));
n++;
}
double sum = 0;
for (double a : decimalValueStorage)
{
sum += a;
}
lblDisplay.setText("The Deciaml Value Is " + sum);
}
}
Beware: in your for loop condition, you have i >= binaryNumber instead of i < binaryNumber, therefore your program will never enter the loop!
And on a side note, why are you using two variables, i and n, for the same purpose (incrementing and accessing the array)?
Edit: another issue:
In binary numbers, lower order bits are to the right, but in arrays, indices are from left to right!!
So you want your rightmost digit to be multiplied by 2^0, the next one right to its left by 2^1, and so on.
But in your code, what is happening is the opposite: it is the leftmost digit (your digit at index 0) that is being multiplied by 2^0!
To fix, you can either:
1) reverse your binaryDigits array before starting to convert, and keep the rest of your code untouched
2) replace decimalValueStorage[n] = binaryValueStorage[n] * (Math.pow(2, n)); by decimalValueStorage[n] = binaryValueStorage[n] * (Math.pow(2, binaryNumber - n));
Hope this helps!
Well, this is a lot to throw at you, but this is how I'd attack this problem:
public class BinaryToDecimalTest {
private static long binaryToDecimal(String binaryInput)
{
long sum = 0;
for (int i = 0 ; i < binaryInput.length() ; i++) {
sum *= 2;
if (binaryInput.charAt(i) == '1')
sum += 1;
}
return sum;
}
private static void test(String binaryInput) {
long n = binaryToDecimal(binaryInput);
System.out.println(String.format("The Deciaml Value of %s Is %d", binaryInput, n));
}
public static void main(String...args) {
test("0100");
test("1011");
test("1011");
test("10000000");
test("10000000000000000");
}
}
Result:
The Deciaml Value of 0100 Is 4
The Deciaml Value of 1011 Is 11
The Deciaml Value of 1010 Is 10
The Deciaml Value of 10000000 Is 128
The Deciaml Value of 10000000000000000 Is 65536
I don't want to just hit you with code, but I didn't know where to start given all of the issues with your code. I wanted you to see how directly you can often attack a problem. I'd be happy to keep working with you, and explain what's going on here.
The one dirty trick I'm using is multiplying the entire accumulated sum by two each time around. This lets you work naturally from the front of the array, rather than having to work your way backwards. The first digit gets multiplied by 2 (length - 1) times, the second (length - 2) times, etc., down to the last number, which doesn't get multiplied at all.

Print all numbers whose nonzero digits are in ascending order

I'm trying to write a program which takes as arguments a number of digits and a base, and counts upward through the numbers that have their nonzero digits in ascending order. For instance, in base 4 with 3 digits, it should print:
000 001 002 003 010 011 012 013 020 022 023 030 033 100 101 102 103
110 111 112 113 120 122 123 130 133 200 202 203 220 222 223 230 233
300 303 330 333
and in base 3 with 4 digits it should print:
0000 0001 0002 0010 0011 0012 0020 0022 0100 0101 0102 0110 0111 0112
0120 0122 0200 0202 0220 0222 1000 1001 1002 1010 1011 1012 1020 1022
1100 1101 1102 1110 1111 1112 1120 1122 1200 1202 1220 1222 2000 2002
2020 2022 2200 2202 2220 2222
I have done this successfully, but my algorithm seems unnecessarily complicated and time-consuming (time is very important for my application). Is there any way of either making it faster, or simplifying it if the speed cannot be improved?
Here is the program:
public static void count(int base, int size)
{
int[] array = new int[size];
print(array); // private print method prints out the array
int index = 0;
while (index < array.length)
{
if (array[index] < base - 1)
{
// check whether we need to increase array[index] by extra to maintain the order
if (array[index] == 0)
{
int i;
// search for the next nonzero digit
// this search seems to take unnecessary time; is there a faster alternative?
for (i = index + 1; i < array.length && array[i] == 0; i++);
// check whether there was, in fact, some later nonzero digit
if (i < array.length) array[index] = array[i];
else array[index] = 1;
}
else array[index]++;
print(array);
index = 0;
}
// carry over to the next digit
else array[index++] = 0;
}
}
I would go for a recursive solution:
public static void count(int base, int size) {
int[] configuration = new int[size];
placeDigits(configuration, base, 0, 1);
}
public static void placeDigits(int[] configuration, int base, int pos, int minNonZero) {
if (pos >= configuration.length) {
print(configuration);
} else {
// 0 is a possible candidate
configuration[pos] = 0;
placeDigits(configuration, base, pos + 1, minNonZero);
// digits between minNonZero and base
for (int d = minNonZero; d < base; d++) {
configuration[pos] = d;
placeDigits(configuration, base, pos + 1, d);
}
}
}
It places digits one after the other into the array and observes the constraint that the non-zero digits must be non decreasing.
Okay, this is a bit of a cheat, but here's a solution expressed in pseudocode:
results : list
for i in 1..max
if '0' not in str(i)
append i to results
fi
rof
print results
On the other hand, is it a cheat? "numbers with nonzero digits" is inherently a question about the decimal representation of the numbers, not in some sense the numbers themselves.
Time complexity is O(n) of course -- at least counting str(i) as a single step, which is where it is a little bit of a cheat.
Just for fun, here's the same solution in Python:
print [i for i in xrange(max) if '0' not in str(i)]
And a sketch of a recursive solution:
Let dig be a list of the nonzero digits, i.e., ['1','2','3','4','5','6','7','8','9']. Enumerate all strings on that list of length ceil(log10(max)) (quiz question, why that limit?).
Print those strings in order, stopping when max is exceeded.
If you don't mind keeping the numbers in memory, you could code the following algorithm:
Start with the numbers 0,1...base-1
For each added digit, d, first add zero, then all previous numbers that begin with digits d or higher (indexing those by starting digit and number of digits, you could access them directly).
Or, as some like to phrase, dp style: Let dp[i][j] represent the sequence of numbers with i digits and left-most digit j. Then dp[i][j] = [d] ++ map (d +) dp[l][k], for all l < i and k >= j, where d = j * 10 ^ (i - 1)
(I borrowed the ++ from Haskell, where it often means to concat lists).
For example, base 4, 3 digits:
Start with one digit:
0,1,2,3
Add to the second digit from the first sequence:
10,11,12,13
20,22,23
30,33
Third digit, add from all previous sequences:
100,101,102,103
110,111,112,113
120,122,123
130,133
200,202,203
220,222,223
230,233
300,303
330,333
JavaScript code:
var base = 4;
var dp = [,[]];
for (var j=0; j<base; j++){
dp[1][j] = [j];
}
for (var i=2; i<4; i++){
dp[i] = [];
for (var j=1; j<base; j++){
var d = j * Math.pow(10,i - 1);
dp[i][j] = [d];
for (var l=1; l<i; l++){
for (var k=j; k<base; k++){
dp[i][j] = dp[i][j].concat(
dp[l][k].map(function(x){
return d + x;
}));
}
}
}
}
console.log(JSON.stringify(dp))
/*
[null,[[0],[1],[2],[3]]
,[null,[10,11,12,13]
,[20,22,23]
,[30,33]]
,[null,[100,101,102,103,110,111,112,113,120,122,123,130,133]
,[200,202,203,220,222,223,230,233]
,[300,303,330,333]]]
*/
Late to the party for this faster answer:
Base 8
Size 20 digits
Current solution: 79 seconds (76~82)
Solution below: 23 seconds (22~24)
Possible numbers: 12245598208
without prints. Principle:
The rule "a digit may be followed by a 0 or a digit >= preceding ones" is also valid for (valid) groups of digits: "a group may be followed by a group of zeroes, or a group which smaller digit is >= any of the preceding ones among the preceding groups". Processing is done at the group level, rather than at the digit level.
Given T total size, and N smaller number of digits in each group (T % N == 0), by calculating all possible groups of N digits they can then be assembled together (T / N groups per solution).
pre-calculate all possible digits on a smaller size, eg 5 (2668 numbers), in an array (takes less than half a second)
keep the maximum digit for each of the "parts" in another array
set in another "atleast" array the indexes of groups based on their smaller digit
build the large numbers by sticking all possible chunks (eg 4x5), provided that the lower digit of a group has to be >= highest of the preceding groups.
Sample code to precalculate the small chunks (parts)
static ArrayList<int[]> parts = new ArrayList<int[]>();
static ArrayList<ArrayList<Integer>> atleast = new ArrayList<ArrayList<Integer>>();
static ArrayList<Integer> maxi = new ArrayList<Integer>();
static int stick[];
static int base;
static long num = 0;
public static void makeParts(int min, int ptr)
{
int me = 0;
do {
array[ptr] = me;
if (ptr > 0) makeParts(Math.max(me,min), ptr-1);
else {
// add part
int[] newa = new int [array.length];
int i,mi,ma,last=array.length-1;
for (i=0 ; i<array.length ; i++) newa[i] = array[i];
parts.add(newa);
// maxi
for (i=0 ; i<=last && newa[i]==0 ; i++) /* */;
maxi.add(ma = i<=last ? newa[i] : 0);
// mini
for (i=last ; i>=0 && newa[i]==0 ; i--) /* */;
mi = i>=0 ? newa[i] : 0;
// add to atleast lists
int pi = parts.size() - 1;
ArrayList<Integer> l;
int imi = mi == 0 ? base-1 : mi;
for (i=0 ; i<=imi ; i++) {
if (i < atleast.size()) l = atleast.get(i);
else {
l = new ArrayList<Integer>();
atleast.add(i, l);
}
l.add(pi);
}
}
me = me == 0 ? (min > 0 ? min : 1) : me+1;
} while (me < base);
}
Sticking the "parts"
public static void stickParts(int minv, int ptr)
{
// "atleast" gives indexes in "parts" of groups which min digit
// is at least "minv" (or only zeroes)
for (int pi: atleast.get(minv)) {
stick[ptr] = pi;
if (ptr > 0) {
stickParts(Math.max(minv,maxi.get(pi)), ptr-1);
}
else {
// count solutions
// the number is made of "parts" from indexes
// stored in "stick"
num++;
}
}
}
Calling this in "main"
base = 8;
int leng = 20;
int pleng = 4;
array = new int [pleng];
makeParts(0,array.length-1);
num = 0;
stick = new int [leng / pleng];
stickParts(0, (leng/pleng) - 1);
out.print(String.format("Got %d numbers\n", num));
If T (total size) is prime, for instance, another specific group has to be calculated, eg for size 17, we could have 3 groups (of 5 digits) + one group of two digits.
Quite an interesting program you have written.
I've tried to increase the performance of the nested search, but so far I haven't found a way to make the worst-case scenario of searching for the next nonzero digit less than O(n).
In the worst-case scenario, the subarray A[i..array.length-1] is not sorted, and array[i] = 0,therefore to find the next non-zero digit, you have to do a linear search.
Aditionally, if there is no next non-zero digit, you have to search the whole array to "find it".
(For example: we have that i = 1 for the sequence '0040'. The subarray [0, 4, 0] is not sorted, so you have to do a linear search to find the next largest/smallest nonzero digit, which would be located in array[2])
The complexity for the worst case will be O(n).
Can you improve running time? I guess you can if you do some parallel programming, but I have no knowledge of that field to help you, unfortunately.
This recursive function tries to avoid any unnecessary loop
public static void count0(int min, int ptr)
{
int me = 0; // joker
do {
array[ptr] = me;
if (ptr > 0) count0(Math.max(me,min), ptr-1);
else print(array);
me = me == 0 ? (min > 0 ? min : 1) : me+1;
} while (me < base);
}
Called like this (base 8 for length of 17) to carry less arguments:
static int array[];
static int base;
int leng = 17;
base = 8;
array = new int [leng];
count0 (0, array.length-1);
Recursivity has its price, though.
I didn't measure performance, but think my code is better readable.
The idea is, to produce every number of base b and length l by Integer-iteration from 0 to the known number in decimal, using the Java-build-in conversion decimal to base b, then removing the zeros in that number (which is of type String) and testing for ascending order.
The output has to be padded with zeros, so therefore the complicated printf in the end.
public static boolean isAscending (String digits) {
for (int i = 1; i < digits.length (); ++i)
if (digits.charAt (i-1) > digits.charAt (i))
return false;
return true;
}
public static void count (int base, int size)
{
/**
Build numbers,i.e. from 000 to 333, for base 4 at length 3
or 4^3 = 4*4*4 = 64 combinations
*/
double max = Math.pow (base, size);
for (int i = 0; i < max; ++i)
{
String res = Integer.toString (i, base);
if (isAscending (res.replaceAll ("0", "")))
System.out.printf ("%0"+size+"d ", Long.parseLong (res));
}
}

generation of random output 3n+1 pblm

I have been trying to solve the 3n+1 question in java.However my output seems to be very random. The question is
Consider the following algorithm:
1. input n
2. print n
3. if n = 1 then STOP
4. if n is odd then tex2html_wrap_inline44
5. else tex2html_wrap_inline46
6. GOTO 2
Given the input 22, the following sequence of numbers will be printed 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
It is conjectured that the algorithm above will terminate (when a 1 is printed) for any integral input value. Despite the simplicity of the algorithm, it is unknown whether this conjecture is true. It has been verified, however, for all integers n such that 0 < n < 1,000,000 (and, in fact, for many more numbers than this.)
Given an input n, it is possible to determine the number of numbers printed (including the 1). For a given n this is called the cycle-length of n. In the example above, the cycle length of 22 is 16.
For any two numbers i and j you are to determine the maximum cycle length over all numbers between i and j.
The Input
The input will consist of a series of pairs of integers i and j, one pair of integers per line. All integers will be less than 1,000,000 and greater than 0.
You should process all pairs of integers and for each pair determine the maximum cycle length over all integers between and including i and j.
You can assume that no operation overflows a 32-bit integer.
The Output
For each pair of input integers i and j you should output i, j, and the maximum cycle length for integers between and including i and j. These three numbers should be separated by at least one space with all three numbers on one line and with one line of output for each line of input. The integers i and j must appear in the output in the same order in which they appeared in the input and should be followed by the maximum cycle length (on the same line).
My code is as given below
class CC
{
int c,f,l,m;
int returnCount(int i,int j)
{
f=0;
for(int k=i;k<=j;k++)
{
l=k;
c=0;
while(l>1)
{
if(l%2==0)
{
l=l/2;
c++;
}
else
{
l=3*l+1;
c++;
}
}
if(f<c)
f=++c;
}
return f;
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int i,j;
CC obj=new CC();
while(sc.hasNextInt())
{
i=sc.nextInt();
j=sc.nextInt();
System.out.println(i+" "+j+" "+obj.returnCount(i,j));
}}}
Now my Input is
605293 606510
956739 956006
826611 825983
756134 756776
478642 479101
815892 815933
719220 719135
929349 929040
And expected output is
605293 606510 341
956739 956006 352
826611 825983 313
756134 756776 362
478642 479101 338
815892 815933 269
719220 719135 274
929349 929040 339
However my output is
605293 606510 341
956739 956006 0
826611 825983 0
756134 756776 362
478642 479101 338
815892 815933 269
719220 719135 0
929349 929040 0
Please help me find the mistake
The problem is that your in your first line the first number is smaller than the second one, but in the second line the first number is bigger than the second one. You have to switch the numbers or find out the bigger one upfront like that:
import java.util.Scanner;
public class CC {
int c, f, l, m;
int returnCount(int i, int j) {
int smaller = Math.min(i, j);
int bigger = Math.max(i, j);
f = 0;
for (int k = smaller; k <= bigger; k++) {
l = k;
c = 0;
while (l > 1) {
if (l % 2 == 0) {
l = l / 2;
c++;
} else {
l = 3 * l + 1;
c++;
}
}
if (f < c)
f = ++c;
}
return f;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int i, j;
CC obj = new CC();
while (sc.hasNextInt()) {
i = sc.nextInt();
j = sc.nextInt();
System.out.println(i + " " + j + " " + obj.returnCount(i, j));
}
}
}
The input and output looks then like that:
956739
956006
956739 956006 352

Count All Permutations Where No Two Adjacent Characters Are the Same

Given a sequence which contains only various amounts of the numbers 1, 2, 3, and 4 (examples: 13244, 4442, etc), I want to count all its permutations such that no two adjacent numbers are the same. I believe it is O(N! * N) and want to know if there is a better one out there. Anyone have any ideas?
class Ideone
{
static int permutationCount++;
public static void main(String[] args) {
String str = "442213";
permutation("", str);
System.out.println(permutationCount);
}
private static void permutation(String prefix, String str) {
int n = str.length();
if (n == 0){
boolean bad = false;
//Check whether there are repeating adjacent characters
for(int i = 0; i < prefix.length()-1; i++){
if(prefix.charAt(i)==prefix.charAt(i+1))
bad = true;
}
if(!bad){
permutationCount++;
}
}
else {
//Recurse through permutations
for (int i = 0; i < n; i++)
permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));
}
}
}
I understand your question like this: Given a string containing only numbers 1,2,3,4 - how many permutations of these characters exist that when you put them into string again there won't be any same adjecent numbers.
I would suggest this approach:
L - length of your string
n1 - how many times is 1 repeated, n2 - how many times is 2 repeated etc.
P - number of all possible permutations
P = L! / (n1!*n2!*n3!*n4!)
C - number of all solutions fitting your constraint
C = P - start with all permutations
substract all permutations which have 11 in it (just take 11 as one number)
C = C - (L - 1)! / ((n1 - 1)! * n2! * n3! * n4!)
... do the same for 22 ...
add all permutations which have both 11 and 22 in it (because we have substracted them twice, so you need to add them)
C = C + (L - 2)! / ((n1 - 1)! * (n2 - 1)! * n3! * n4!)
... repeat previous steps for 33 and 44 ...
If you just want to calculate how many permutations match your constraint, it is not required to spell each of them out.
If I get your question right, your input string has 4 distinct input characters 1,2,3,4 and you want to know how many permutations of this are possible?
Then you should use some maths, namely n! / (n-r)!, where n is the number of elements to choose from (4 in this case) and r is the number of positions you want to fill (also 4).
Your example would have 4! / (4-4)! = 24 permutations possible:
{1,2,3,4} {1,2,4,3} {1,3,2,4} {1,3,4,2} {1,4,2,3} {1,4,3,2}
{2,1,3,4} {2,1,4,3} {2,3,1,4} {2,3,4,1} {2,4,1,3} {2,4,3,1}
{3,1,2,4} {3,1,4,2} {3,2,1,4} {3,2,4,1} {3,4,1,2} {3,4,2,1}
{4,1,2,3} {4,1,3,2} {4,2,1,3} {4,2,3,1} {4,3,1,2} {4,3,2,1}
In a nutshell, for length n with n distinct values the count of permutations is n!:
1 -> 1
2 -> 2
3 -> 6
4 -> 24
5 -> 120
...
Edit: After your edits and comments it is clear that I misunderstood the question.
If you just want to check to see if there are no matching adjacent numbers, then you can use a simple loop. This will be O(n) complexity.
public static void main(String[] args) {
String str = "442213";
System.out.println(permutation(str));
}
public static int permutation(String str) {
int permutationCount = 0;
if (str.length() > 1) {
for (int i = 0; i < str.length() - 1; i++) {
if (str.charAt(i) != str.charAt(i + 1)) {
permutationCount++;
}
}
}
return permutationCount;
}
If you wanted to stick with recursion, you could do something like this:
public static void main(String[] args) {
String str = "442213";
System.out.println(permutation(str, 0));
}
public static int permutation(String str, int currentIndex) {
int permutationCount = 0;
if (str == null || currentIndex + 1 >= str.length()) {
return permutationCount;
}
if (str.charAt(currentIndex) != str.charAt(currentIndex + 1)) {
permutationCount = 1;
}
return permutationCount + permutation(str, currentIndex + 1);
}

Quickest way to find missing number in an array of numbers

This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
I have an array of numbers from 1 to 100 (both inclusive). The size of the array is 100. The numbers are randomly added to the array, but there is one random empty slot in the array.
What is the quickest way to find that slot as well as the number that should be put in the slot? A Java solution is preferable.
You can do this in O(n). Iterate through the array and compute the sum of all numbers. Now, sum of natural numbers from 1 to N, can be expressed as Nx(N+1)/2. In your case N=100.
Subtract the sum of the array from Nx(N+1)/2, where N=100.
That is the missing number. The empty slot can be detected during the iteration in which the sum is computed.
// will be the sum of the numbers in the array.
int sum = 0;
int idx = -1;
for (int i = 0; i < arr.length; i++)
{
if (arr[i] == 0)
{
idx = i;
}
else
{
sum += arr[i];
}
}
// the total sum of numbers between 1 and arr.length.
int total = (arr.length + 1) * arr.length / 2;
System.out.println("missing number is: " + (total - sum) + " at index " + idx);
We can use XOR operation which is safer than summation because in programming languages if the given input is large it may overflow and may give wrong answer.
Before going to the solution, know that A xor A = 0. So if we XOR two identical numbers the value is 0.
Now, XORing [1..n] with the elements present in the array cancels the identical numbers. So at the end we will get the missing number.
// Assuming that the array contains 99 distinct integers between 1..99
// and empty slot value is zero
int XOR = 0;
for(int i=0; i<100; i++) {
if (ARRAY[i] != 0) // remove this condition keeping the body if no zero slot
XOR ^= ARRAY[i];
XOR ^= (i + 1);
}
return XOR;
//return XOR ^ ARRAY.length + 1; if your array doesn't have empty zero slot.
Let the given array be A with length N. Lets assume in the given array, the single empty slot is filled with 0.
We can find the solution for this problem using many methods including algorithm used in Counting sort. But, in terms of efficient time and space usage, we have two algorithms. One uses mainly summation, subtraction and multiplication. Another uses XOR. Mathematically both methods work fine. But programatically, we need to assess all the algorithms with main measures like
Limitations(like input values are large(A[1...N]) and/or number of
input values is large(N))
Number of condition checks involved
Number and type of mathematical operations involved
etc. This is because of the limitations in time and/or hardware(Hardware resource limitation) and/or software(Operating System limitation, Programming language limitation, etc), etc. Lets list and assess the pros and cons of each one of them.
Algorithm 1 :
In algorithm 1, we have 3 implementations.
Calculate the total sum of all the numbers(this includes the unknown missing number) by using the mathematical formula(1+2+3+...+N=(N(N+1))/2). Here, N=100. Calculate the total sum of all the given numbers. Subtract the second result from the first result will give the missing number.
Missing Number = (N(N+1))/2) - (A[1]+A[2]+...+A[100])
Calculate the total sum of all the numbers(this includes the unknown missing number) by using the mathematical formula(1+2+3+...+N=(N(N+1))/2). Here, N=100. From that result, subtract each given number gives the missing number.
Missing Number = (N(N+1))/2)-A[1]-A[2]-...-A[100]
(Note:Even though the second implementation's formula is derived from first, from the mathematical point of view both are same. But from programming point of view both are different because the first formula is more prone to bit overflow than the second one(if the given numbers are large enough). Even though addition is faster than subtraction, the second implementation reduces the chance of bit overflow caused by addition of large values(Its not completely eliminated, because there is still very small chance since (N+1) is there in the formula). But both are equally prone to bit overflow by multiplication. The limitation is both implementations give correct result only if N(N+1)<=MAXIMUM_NUMBER_VALUE. For the first implementation, the additional limitation is it give correct result only if Sum of all given numbers<=MAXIMUM_NUMBER_VALUE.)
Calculate the total sum of all the numbers(this includes the unknown missing number) and subtract each given number in the same loop in parallel. This eliminates the risk of bit overflow by multiplication but prone to bit overflow by addition and subtraction.
//ALGORITHM
missingNumber = 0;
foreach(index from 1 to N)
{
missingNumber = missingNumber + index;
//Since, the empty slot is filled with 0,
//this extra condition which is executed for N times is not required.
//But for the sake of understanding of algorithm purpose lets put it.
if (inputArray[index] != 0)
missingNumber = missingNumber - inputArray[index];
}
In a programming language(like C, C++, Java, etc), if the number of bits representing a integer data type is limited, then all the above implementations are prone to bit overflow because of summation, subtraction and multiplication, resulting in wrong result in case of large input values(A[1...N]) and/or large number of input values(N).
Algorithm 2 :
We can use the property of XOR to get solution for this problem without worrying about the problem of bit overflow. And also XOR is both safer and faster than summation. We know the property of XOR that XOR of two same numbers is equal to 0(A XOR A = 0). If we calculate the XOR of all the numbers from 1 to N(this includes the unknown missing number) and then with that result, XOR all the given numbers, the common numbers get canceled out(since A XOR A=0) and in the end we get the missing number. If we don't have bit overflow problem, we can use both summation and XOR based algorithms to get the solution. But, the algorithm which uses XOR is both safer and faster than the algorithm which uses summation, subtraction and multiplication. And we can avoid the additional worries caused by summation, subtraction and multiplication.
In all the implementations of algorithm 1, we can use XOR instead of addition and subtraction.
Lets assume, XOR(1...N) = XOR of all numbers from 1 to N
Implementation 1 => Missing Number = XOR(1...N) XOR (A[1] XOR A[2] XOR...XOR A[100])
Implementation 2 => Missing Number = XOR(1...N) XOR A[1] XOR A[2] XOR...XOR A[100]
Implementation 3 =>
//ALGORITHM
missingNumber = 0;
foreach(index from 1 to N)
{
missingNumber = missingNumber XOR index;
//Since, the empty slot is filled with 0,
//this extra condition which is executed for N times is not required.
//But for the sake of understanding of algorithm purpose lets put it.
if (inputArray[index] != 0)
missingNumber = missingNumber XOR inputArray[index];
}
All three implementations of algorithm 2 will work fine(from programatical point of view also). One optimization is, similar to
1+2+....+N = (N(N+1))/2
We have,
1 XOR 2 XOR .... XOR N = {N if REMAINDER(N/4)=0, 1 if REMAINDER(N/4)=1, N+1 if REMAINDER(N/4)=2, 0 if REMAINDER(N/4)=3}
We can prove this by mathematical induction. So, instead of calculating the value of XOR(1...N) by XOR all the numbers from 1 to N, we can use this formula to reduce the number of XOR operations.
Also, calculating XOR(1...N) using above formula has two implementations. Implementation wise, calculating
// Thanks to https://a3nm.net/blog/xor.html for this implementation
xor = (n>>1)&1 ^ (((n&1)>0)?1:n)
is faster than calculating
xor = (n % 4 == 0) ? n : (n % 4 == 1) ? 1 : (n % 4 == 2) ? n + 1 : 0;
So, the optimized Java code is,
long n = 100;
long a[] = new long[n];
//XOR of all numbers from 1 to n
// n%4 == 0 ---> n
// n%4 == 1 ---> 1
// n%4 == 2 ---> n + 1
// n%4 == 3 ---> 0
//Slower way of implementing the formula
// long xor = (n % 4 == 0) ? n : (n % 4 == 1) ? 1 : (n % 4 == 2) ? n + 1 : 0;
//Faster way of implementing the formula
// long xor = (n>>1)&1 ^ (((n&1)>0)?1:n);
long xor = (n>>1)&1 ^ (((n&1)>0)?1:n);
for (long i = 0; i < n; i++)
{
xor = xor ^ a[i];
}
//Missing number
System.out.println(xor);
This was an Amazon interview question and was originally answered here: We have numbers from 1 to 52 that are put into a 51 number array, what's the best way to find out which number is missing?
It was answered, as below:
1) Calculate the sum of all numbers stored in the array of size 51.
2) Subtract the sum from (52 * 53)/2 ---- Formula : n * (n + 1) / 2.
It was also blogged here: Software Job - Interview Question
Here is a simple program to find the missing numbers in an integer array
ArrayList<Integer> arr = new ArrayList<Integer>();
int a[] = { 1,3,4,5,6,7,10 };
int j = a[0];
for (int i=0;i<a.length;i++)
{
if (j==a[i])
{
j++;
continue;
}
else
{
arr.add(j);
i--;
j++;
}
}
System.out.println("missing numbers are ");
for(int r : arr)
{
System.out.println(" " + r);
}
Recently I had a similar (not exactly the same) question in a job interview and also I heard from a friend that was asked the exactly same question in an interview.
So here is an answer to the OP question and a few more variations that can be potentially asked.
The answers example are given in Java because, it's stated that:
A Java solution is preferable.
Variation 1:
Array of numbers from 1 to 100 (both inclusive) ... The numbers are randomly added to the array, but there is one random empty slot in the array
public static int findMissing1(int [] arr){
int sum = 0;
for(int n : arr){
sum += n;
}
return (100*(100+1)/2) - sum;
}
Explanation:
This solution (as many other solutions posted here) is based on the formula of Triangular number, which gives us the sum of all natural numbers from 1 to n (in this case n is 100). Now that we know the sum that should be from 1 to 100 - we just need to subtract the actual sum of existing numbers in given array.
Variation 2:
Array of numbers from 1 to n (meaning that the max number is unknown)
public static int findMissing2(int [] arr){
int sum = 0, max = 0;
for(int n : arr){
sum += n;
if(n > max) max = n;
}
return (max*(max+1)/2) - sum;
}
Explanation:
In this solution, since the max number isn't given - we need to find it. After finding the max number - the logic is the same.
Variation 3:
Array of numbers from 1 to n (max number is unknown), there is two random empty slots in the array
public static int [] findMissing3(int [] arr){
int sum = 0, max = 0, misSum;
int [] misNums = {};//empty by default
for(int n : arr){
sum += n;
if(n > max) max = n;
}
misSum = (max*(max+1)/2) - sum;//Sum of two missing numbers
for(int n = Math.min(misSum, max-1); n > 1; n--){
if(!contains(n, arr)){
misNums = new int[]{n, misSum-n};
break;
}
}
return misNums;
}
private static boolean contains(int num, int [] arr){
for(int n : arr){
if(n == num)return true;
}
return false;
}
Explanation:
In this solution, the max number isn't given (as in the previous), but it can also be missing of two numbers and not one. So at first we find the sum of missing numbers - with the same logic as before. Second finding the smaller number between missing sum and the last (possibly) missing number - to reduce unnecessary search. Third since Javas Array (not a Collection) doesn't have methods as indexOf or contains, I added a small reusable method for that logic. Fourth when first missing number is found, the second is the subtract from missing sum.
If only one number is missing, then the second number in array will be zero.
Variation 4:
Array of numbers from 1 to n (max number is unknown), with X missing (amount of missing numbers are unknown)
public static ArrayList<Integer> findMissing4(ArrayList<Integer> arr){
int max = 0;
ArrayList<Integer> misNums = new ArrayList();
int [] neededNums;
for(int n : arr){
if(n > max) max = n;
}
neededNums = new int[max];//zero for any needed num
for(int n : arr){//iterate again
neededNums[n == max ? 0 : n]++;//add one - used as index in second array (convert max to zero)
}
for(int i=neededNums.length-1; i>0; i--){
if(neededNums[i] < 1)misNums.add(i);//if value is zero, than index is a missing number
}
return misNums;
}
Explanation:
In this solution, as in the previous, the max number is unknown and there can be missing more than one number, but in this variation, we don't know how many numbers are potentially missing (if any). The beginning of the logic is the same - find the max number. Then I initialise another array with zeros, in this array index indicates the potentially missing number and zero indicates that the number is missing. So every existing number from original array is used as an index and its value is incremented by one (max converted to zero).
Note
If you want examples in other languages or another interesting variations of this question, you are welcome to check my Github repository for Interview questions & answers.
(sum of 1 to n) - (sum of all values in the array) = missing number
int sum = 0;
int idx = -1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 0) idx = i; else sum += arr[i];
}
System.out.println("missing number is: " + (5050 - sum) + " at index " + idx);
On a similar scenario, where the array is already sorted, it does not include duplicates and only one number is missing, it is possible to find this missing number in log(n) time, using binary search.
public static int getMissingInt(int[] intArray, int left, int right) {
if (right == left + 1) return intArray[right] - 1;
int pivot = left + (right - left) / 2;
if (intArray[pivot] == intArray[left] + (intArray[right] - intArray[left]) / 2 - (right - left) % 2)
return getMissingInt(intArray, pivot, right);
else
return getMissingInt(intArray, left, pivot);
}
public static void main(String args[]) {
int[] array = new int[]{3, 4, 5, 6, 7, 8, 10};
int missingInt = getMissingInt(array, 0, array.length-1);
System.out.println(missingInt); //it prints 9
}
Well, use a bloom filter.
int findmissing(int arr[], int n)
{
long bloom=0;
int i;
for(i=0; i<;n; i++)bloom+=1>>arr[i];
for(i=1; i<=n, (bloom<<i & 1); i++);
return i;
}
This is c# but it should be pretty close to what you need:
int sumNumbers = 0;
int emptySlotIndex = -1;
for (int i = 0; i < arr.length; i++)
{
if (arr[i] == 0)
emptySlotIndex = i;
sumNumbers += arr[i];
}
int missingNumber = 5050 - sumNumbers;
The solution that doesn't involve repetitive additions or maybe the n(n+1)/2 formula doesn't get to you at an interview time for instance.
You have to use an array of 4 ints (32 bits) or 2 ints (64 bits). Initialize the last int with (-1 & ~(1 << 31)) >> 3. (the bits that are above 100 are set to 1) Or you may set the bits above 100 using a for loop.
Go through the array of numbers and set 1 for the bit position corresponding to the number (e.g. 71 would be set on the 3rd int on the 7th bit from left to right)
Go through the array of 4 ints (32 bit version) or 2 ints(64 bit version)
public int MissingNumber(int a[])
{
int bits = sizeof(int) * 8;
int i = 0;
int no = 0;
while(a[i] == -1)//this means a[i]'s bits are all set to 1, the numbers is not inside this 32 numbers section
{
no += bits;
i++;
}
return no + bits - Math.Log(~a[i], 2);//apply NOT (~) operator to a[i] to invert all bits, and get a number with only one bit set (2 at the power of something)
}
Example: (32 bit version) lets say that the missing number is 58. That means that the 26th bit (left to right) of the second integer is set to 0.
The first int is -1 (all bits are set) so, we go ahead for the second one and add to "no" the number 32. The second int is different from -1 (a bit is not set) so, by applying the NOT (~) operator to the number we get 64. The possible numbers are 2 at the power x and we may compute x by using log on base 2; in this case we get log2(64) = 6 => 32 + 32 - 6 = 58.
Hope this helps.
I think the easiest and possibly the most efficient solution would be to loop over all entries and use a bitset to remember which numbers are set, and then test for 0 bit. The entry with the 0 bit is the missing number.
This is not a search problem. The employer is wondering if you have a grasp of a checksum. You might need a binary or for loop or whatever if you were looking for multiple unique integers, but the question stipulates "one random empty slot." In this case we can use the stream sum. The condition: "The numbers are randomly added to the array" is meaningless without more detail. The question does not assume the array must start with the integer 1 and so tolerate with the offset start integer.
int[] test = {2,3,4,5,6,7,8,9,10, 12,13,14 };
/*get the missing integer*/
int max = test[test.length - 1];
int min = test[0];
int sum = Arrays.stream(test).sum();
int actual = (((max*(max+1))/2)-min+1);
//Find:
//the missing value
System.out.println(actual - sum);
//the slot
System.out.println(actual - sum - min);
Success time: 0.18 memory: 320576 signal:0
I found this beautiful solution here:
http://javaconceptoftheday.com/java-puzzle-interview-program-find-missing-number-in-an-array/
public class MissingNumberInArray
{
//Method to calculate sum of 'n' numbers
static int sumOfNnumbers(int n)
{
int sum = (n * (n+1))/ 2;
return sum;
}
//Method to calculate sum of all elements of array
static int sumOfElements(int[] array)
{
int sum = 0;
for (int i = 0; i < array.length; i++)
{
sum = sum + array[i];
}
return sum;
}
public static void main(String[] args)
{
int n = 8;
int[] a = {1, 4, 5, 3, 7, 8, 6};
//Step 1
int sumOfNnumbers = sumOfNnumbers(n);
//Step 2
int sumOfElements = sumOfElements(a);
//Step 3
int missingNumber = sumOfNnumbers - sumOfElements;
System.out.println("Missing Number is = "+missingNumber);
}
}
function solution($A) {
// code in PHP5.5
$n=count($A);
for($i=1;$i<=$n;$i++) {
if(!in_array($i,$A)) {
return (int)$i;
}
}
}
Finding the missing number from a series of numbers. IMP points to remember.
the array should be sorted..
the Function do not work on multiple missings.
the sequence must be an AP.
public int execute2(int[] array) {
int diff = Math.min(array[1]-array[0], array[2]-array[1]);
int min = 0, max = arr.length-1;
boolean missingNum = true;
while(min<max) {
int mid = (min + max) >>> 1;
int leftDiff = array[mid] - array[min];
if(leftDiff > diff * (mid - min)) {
if(mid-min == 1)
return (array[mid] + array[min])/2;
max = mid;
missingNum = false;
continue;
}
int rightDiff = array[max] - array[mid];
if(rightDiff > diff * (max - mid)) {
if(max-mid == 1)
return (array[max] + array[mid])/2;
min = mid;
missingNum = false;
continue;
}
if(missingNum)
break;
}
return -1;
}
One thing you could do is sort the numbers using quick sort for instance. Then use a for loop to iterate through the sorted array from 1 to 100. In each iteration, you compare the number in the array with your for loop increment, if you find that the index increment is not the same as the array value, you have found your missing number as well as the missing index.
Below is the solution for finding all the missing numbers from a given array:
public class FindMissingNumbers {
/**
* The function prints all the missing numbers from "n" consecutive numbers.
* The number of missing numbers is not given and all the numbers in the
* given array are assumed to be unique.
*
* A similar approach can be used to find all no-unique/ unique numbers from
* the given array
*
* #param n
* total count of numbers in the sequence
* #param numbers
* is an unsorted array of all the numbers from 1 - n with some
* numbers missing.
*
*/
public static void findMissingNumbers(int n, int[] numbers) {
if (n < 1) {
return;
}
byte[] bytes = new byte[n / 8];
int countOfMissingNumbers = n - numbers.length;
if (countOfMissingNumbers == 0) {
return;
}
for (int currentNumber : numbers) {
int byteIndex = (currentNumber - 1) / 8;
int bit = (currentNumber - byteIndex * 8) - 1;
// Update the "bit" in bytes[byteIndex]
int mask = 1 << bit;
bytes[byteIndex] |= mask;
}
for (int index = 0; index < bytes.length - 2; index++) {
if (bytes[index] != -128) {
for (int i = 0; i < 8; i++) {
if ((bytes[index] >> i & 1) == 0) {
System.out.println("Missing number: " + ((index * 8) + i + 1));
}
}
}
}
// Last byte
int loopTill = n % 8 == 0 ? 8 : n % 8;
for (int index = 0; index < loopTill; index++) {
if ((bytes[bytes.length - 1] >> index & 1) == 0) {
System.out.println("Missing number: " + (((bytes.length - 1) * 8) + index + 1));
}
}
}
public static void main(String[] args) {
List<Integer> arrayList = new ArrayList<Integer>();
int n = 128;
int m = 5;
for (int i = 1; i <= n; i++) {
arrayList.add(i);
}
Collections.shuffle(arrayList);
for (int i = 1; i <= 5; i++) {
System.out.println("Removing:" + arrayList.remove(i));
}
int[] array = new int[n - m];
for (int i = 0; i < (n - m); i++) {
array[i] = arrayList.get(i);
}
System.out.println("Array is: " + Arrays.toString(array));
findMissingNumbers(n, array);
}
}
Lets say you have n as 8, and our numbers range from 0-8 for this example
we can represent the binary representation of all 9 numbers as follows
0000
0001
0010
0011
0100
0101
0110
0111
1000
in the above sequence there is no missing numbers and in each column the number of zeros and ones match, however as soon as you remove 1 value lets say 3 we get a in balance in the number of 0's and 1's across the columns. If the number of 0's in a column is <= the number of 1's our missing number will have a 0 at this bit position, otherwise if the number of 0's > the number of 1's at this bit position then this bit position will be a 1. We test the bits left to right and at each iteration we throw away half of the array for the testing of the next bit, either the odd array values or the even array values are thrown away at each iteration depending on which bit we are deficient on.
The below solution is in C++
int getMissingNumber(vector<int>* input, int bitPos, const int startRange)
{
vector<int> zeros;
vector<int> ones;
int missingNumber=0;
//base case, assume empty array indicating start value of range is missing
if(input->size() == 0)
return startRange;
//if the bit position being tested is 0 add to the zero's vector
//otherwise to the ones vector
for(unsigned int i = 0; i<input->size(); i++)
{
int value = input->at(i);
if(getBit(value, bitPos) == 0)
zeros.push_back(value);
else
ones.push_back(value);
}
//throw away either the odd or even numbers and test
//the next bit position, build the missing number
//from right to left
if(zeros.size() <= ones.size())
{
//missing number is even
missingNumber = getMissingNumber(&zeros, bitPos+1, startRange);
missingNumber = (missingNumber << 1) | 0;
}
else
{
//missing number is odd
missingNumber = getMissingNumber(&ones, bitPos+1, startRange);
missingNumber = (missingNumber << 1) | 1;
}
return missingNumber;
}
At each iteration we reduce our input space by 2, i.e N, N/2,N/4 ... = O(log N), with space O(N)
//Test cases
[1] when missing number is range start
[2] when missing number is range end
[3] when missing number is odd
[4] when missing number is even
Solution With PHP $n = 100;
$n*($n+1)/2 - array_sum($array) = $missing_number
and array_search($missing_number) will give the index of missing number
Here program take time complexity is O(logn) and space complexity O(logn)
public class helper1 {
public static void main(String[] args) {
int a[] = {1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12};
int k = missing(a, 0, a.length);
System.out.println(k);
}
public static int missing(int[] a, int f, int l) {
int mid = (l + f) / 2;
//if first index reached last then no element found
if (a.length - 1 == f) {
System.out.println("missing not find ");
return 0;
}
//if mid with first found
if (mid == f) {
System.out.println(a[mid] + 1);
return a[mid] + 1;
}
if ((mid + 1) == a[mid])
return missing(a, mid, l);
else
return missing(a, f, mid);
}
}
public class MissingNumber {
public static void main(String[] args) {
int array[] = {1,2,3,4,6};
int x1 = getMissingNumber(array,6);
System.out.println("The Missing number is: "+x1);
}
private static int getMissingNumber(int[] array, int i) {
int acctualnumber =0;
int expectednumber = (i*(i+1)/2);
for (int j : array) {
acctualnumber = acctualnumber+j;
}
System.out.println(acctualnumber);
System.out.println(expectednumber);
return expectednumber-acctualnumber;
}
}
Use sum formula,
class Main {
// Function to ind missing number
static int getMissingNo (int a[], int n) {
int i, total;
total = (n+1)*(n+2)/2;
for ( i = 0; i< n; i++)
total -= a[i];
return total;
}
/* program to test above function */
public static void main(String args[]) {
int a[] = {1,2,4,5,6};
int miss = getMissingNo(a,5);
System.out.println(miss);
}
}
Reference http://www.geeksforgeeks.org/find-the-missing-number/
simple solution with test data :
class A{
public static void main(String[] args){
int[] array = new int[200];
for(int i=0;i<100;i++){
if(i != 51){
array[i] = i;
}
}
for(int i=100;i<200;i++){
array[i] = i;
}
int temp = 0;
for(int i=0;i<200;i++){
temp ^= array[i];
}
System.out.println(temp);
}
}
//Array is shorted and if writing in C/C++ think of XOR implementations in java as follows.
int num=-1;
for (int i=1; i<=100; i++){
num =2*i;
if(arr[num]==0){
System.out.println("index: "+i+" Array position: "+ num);
break;
}
else if(arr[num-1]==0){
System.out.println("index: "+i+ " Array position: "+ (num-1));
break;
}
}// use Rabbit and tortoise race, move the dangling index faster,
//learnt from Alogithimica, Ameerpet, hyderbad**
If the array is randomly filled, then at the best you can do a linear search in O(n) complexity. However, we could have improved the complexity to O(log n) by divide and conquer approach similar to quick sort as pointed by giri given that the numbers were in ascending/descending order.
This Program finds missing numbers
<?php
$arr_num=array("1","2","3","5","6");
$n=count($arr_num);
for($i=1;$i<=$n;$i++)
{
if(!in_array($i,$arr_num))
{
array_push($arr_num,$i);print_r($arr_num);exit;
}
}
?>
Now I'm now too sharp with the Big O notations but couldn't you also do something like (in Java)
for (int i = 0; i < numbers.length; i++) {
if(numbers[i] != i+1){
System.out.println(i+1);
}
}
where numbers is the array with your numbers from 1-100.
From my reading of the question it did not say when to write out the missing number.
Alternatively if you COULD throw the value of i+1 into another array and print that out after the iteration.
Of course it might not abide by the time and space rules. As I said. I have to strongly brush up on Big O.
========Simplest Solution for sorted Array===========
public int getMissingNumber(int[] sortedArray)
{
int missingNumber = 0;
int missingNumberIndex=0;
for (int i = 0; i < sortedArray.length; i++)
{
if (sortedArray[i] == 0)
{
missingNumber = (sortedArray[i + 1]) - 1;
missingNumberIndex=i;
System.out.println("missingNumberIndex: "+missingNumberIndex);
break;
}
}
return missingNumber;
}
Another homework question. A sequential search is the best that you can do. As for a Java solution, consider that an exercise for the reader. :P

Categories