How to Find Missing Number on Integer Array of 1 to 100? - java

Here is what i did. What can i do further? Can anybody suggest? I am looking for bitset solution.
public static void main(String args[]) {
// one missing number
printMissingNumber(new int[]{1, 2, 3, 4, 6}, 6);
// two missing number
printMissingNumber(new int[]{1, 2, 3, 4, 6, 7, 9, 8, 10}, 10);
// three missing number
printMissingNumber(new int[]{1, 2, 3, 4, 6, 9, 8}, 10);
// four missing number
printMissingNumber(new int[]{1, 2, 3, 4, 9, 8}, 10);
// Only one missing number in array
int[] iArray = new int[]{1, 2, 3, 5};
int missing = getMissingNumber(iArray, 5);
System.out.printf("Missing number in array %s is %d %n",
Arrays.toString(iArray), missing);
}

For n sequential numbers, the sum s = n(n+1)/2.
Sum up the numbers in the array and subtract it from s to find the missing number.

If n is the largest number, and there is only one missing, then the missing number is
n * (n + 1) / 2 - sum{elements in your array}
The first term is the sum of n consecutive integers from 1 to, and including, n.

Related

Find number x equal to sum of 1 number from n sets

I'm having the following problem:
I have n sorted collections of integers (2<n<10).
I have a number x.
I wanna know if there is a sum (there can be multiple), in which each set needs to contribute exactly 1 number, which is equal to x
Example 1:
Collection 1: {1, 2, 3, 5, 7, 8}
Collection 2: {2, 4, 4, 5, 6, 8, 9, 11 23}
x: 9
For this example, a possible sum is 5+4. Another possibility is 1+8.
Example2:
Collection 1: {1, 1, 5, 7, 8, 9}
Collection 2: {2, 4, 5, 6, 8, 9}
x: 8
In this example, there is no possible sum. The number 8 is in both collections but since all collections need to contribute in the summation, this doesn't matter.
I don't wanna brute force this so i'm thinking recursion could make this process a bit faster but i don't really know where to begin.
I'm looking for some kind of train of thought although pseudo code or working code (java) would be appreciated :)
Try this.
static boolean existSum(List<Collection<Integer>> collections, int x) {
int size = collections.size();
return new Object() {
boolean find(int index, int sum) {
if (index >= size)
return sum == x;
for (int i : collections.get(index)) {
int newSum = sum + i;
if (newSum > x)
break;
if (find(index + 1, newSum))
return true;
}
return false;
}
}.find(0, 0);
}
public static void main(String[] args) throws Exception {
System.out.println(existSum(List.of(
List.of(1, 2, 3, 5, 7, 8),
List.of(2, 4, 4, 5, 6, 8, 9, 11, 23)), 9));
System.out.println(existSum(List.of(
List.of(1, 1, 5, 7, 8, 9),
List.of(2, 4, 5, 6, 8, 9)), 8));
}
output:
true
false

Quicksort went wrong (added some duplicates)

I'm new to sorting algorithms and can't seem to figure out what went wrong. With an unsorted array of int [] uArr = {5,2, 10, 7, 6, 0, 8, 1, 9}, i'm given 0,1,2,5,5,6,8,10 (the nine in the org. array was replaced with a duplicate 5 and the 7 was lost). If I add duplicates to the array, I get more duplicates after the array is sorted and a few more missing numbers.
public static void main(String args[]){
int [] uArr = {5,2, 10, 7, 6, 0, 8, 1, 9};
qSort(uArr, 0, 8);
}
public static void qSort(int [] A, int low, int high){
if (low < high){
int pivotL = partition(A, low, high);
qSort(A, low, pivotL);
qSort(A, pivotL+1, high);
}
}
public static int partition(int [] arr, int low, int high){
int pivot = arr[low];
int leftwall = low;
for (int i = low + 1; i < high; i++){
if (arr[i] < pivot){
int temp = arr[i];
arr[i] = arr[leftwall];
arr[leftwall] = temp;
leftwall += 1;
}
}
int temp2 = pivot;
pivot = arr[leftwall];
arr[leftwall] = temp2;
return leftwall;
}
}
So one thing you should seriously do is start writing documentation. Even though this is a small program, you seem to have forgotten what you were doing as you were writing the code.
For example, there are 9 elements in the array, and you pass in the offsets to sort, inclusive, as 0 through 8:
qSort( uArr, 0, 8 );
But then in the partition routine you only sort elements less than the high value:
for( int i = low + 1; i < high; i++ ) {
And unlike you the last value in the array, 9, is never touched for me and never sorted. So that's an issue. Figure out if you want your indexes to be inclusive or not. For me writing documentation as I go helps me keep these ideas straight.
I'm still looking for other problems like the duplication.
Update: I'm going to just post these as I figure them out, as a sort of stream-of-consciousness of how I look for problems. One thing I was taught early on is that adding print statements to your code can be faster than using a debugger. So (after re-formatting your code, because the formatting you posted was frankly crap) I added this:
public static void qSort( int[] A, int low, int high ) {
System.out.println( Arrays.toString( A ) + " low=" + low + " high=" + high );
And got this output:
run:
[5, 2, 10, 7, 6, 0, 8, 1, 9] low=0 high=8
[2, 0, 1, 5, 6, 5, 8, 10, 9] low=0 high=3
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=0 high=2
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=0 high=0
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=1 high=2
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=1 high=1
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=2 high=2
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=3 high=3
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=4 high=8
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=4 high=5
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=4 high=4
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=5 high=5
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=6 high=8
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=6 high=6
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=7 high=8
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=7 high=7
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=8 high=8
[0, 1, 2, 5, 5, 6, 8, 10, 9]
BUILD SUCCESSFUL (total time: 0 seconds)
I did have to stare at the output for a while, but what I noticed next was two things. The 5 is duplicated almost immediately, and the 5 is also the first element, which means it's going to be chosen by your partition code as the pivot. So it looks as though you have problems re-merging the pivot with the array.
Update 2: OK found another problem. This one I found by writing your array out by hand and walking through each value of i and leftwall as it makes the first partition. Problem here:
When the pivot, 5, encounters the element 0 in the array, the rest of the array has not been sorted. The 10, 7, 6, etc. are not less than the pivot and have not be touched. So when you make the swap, you sawp this:
[2, 5, 10, 7, 6, 0, 8, 1, 9]
for this:
[2, 5, 0, 7, 6, 5, 8, 1, 9]
This is because leftwall was 1 (it had been swapped with the 2 but not any other number, so it only had been incremented once) and there's the duplication and losing numbers too. I'm going to stop there because you have some pretty big problems.
What you need to do in this case is swap the 10, not the pivot, with the 0. This is going to require one additional pointer at least. Quicksort algorithms need to find the lowest and highest in the array and have two loops inside the outer for loop. What you have here is a kind of weird recursive insert sort. You'll need to think a bit more how to do this, but two more loops, nest inside the first, will be required.

Find minimum peak elements in an array

Question: Given an array numbers = {2, 7, 8, 5, 1, 6, 3, 9, 4}. Check the below conditions, both the conditions should be satisfied.
a[i] > a[i-1] or if first element a[i] > a[i+1]
a[i] > a[i+1] or if last element a[lastelement] > a[lastelement - 1]
Therefore:
1st Iteration - 8, 6, 9 are peak values. Remove the smallest ele. Remove 6. New arr {2, 7, 8, 5, 1, 3, 9, 4}. Output Arr - {6}
2nd Iteration - 8, 9 are peak values. Remove the smallest ele. Remove 8. New arr {2, 7, 5, 1, 3, 9, 4}. Output Arr - {6, 8}
3rd Iteration - 7, 9 are peak values. Remove the smallest ele. Remove 7. New arr {2, 5, 1, 3, 9, 4}. Output Arr - {6, 7, 8}
4th Iteration - 5, 9 are peak values. Remove the smallest ele. Remove 5. New arr {2, 1, 3, 9, 4}. Output Arr - {6, 7, 8, 5}
5th Iteration - 2, 9 are peak values. Remove the smallest ele. Remove 2. New arr {1, 3, 9, 4}. Output Arr - {6, 7, 8, 5, 2}
6th Iteration - 9 are peak values. Remove the smallest ele. Remove 9. New arr {1, 3, 4}. Output Arr - {6, 7, 8, 5, 2, 9}
7th Iteration - 4 are peak values. Remove the smallest ele. Remove 4. New arr {1, 3}. Output Arr - {6, 7, 8, 5, 2, 9, 4}
8th Iteration - 3 are peak values. Remove the smallest ele. Remove 3. New arr {1}. Output Arr - {6, 7, 8, 5, 2, 9, 4, 3}
9th Iteration - 1 are peak values. Remove the smallest ele. Remove 1. New arr {1}. Output Arr - {6, 7, 8, 5, 2, 9, 4, 3, 1}
Output: {6, 8, 7, 5, 2, 9, 4, 3, 1}
My solution is working but I am looking for optimized solution. Please let me know.
Here is my code:
public int[] findMinimumPeaks(int[] arr){
List<Integer> list1 = new ArrayList<Integer>(arr.length);
int[] output = new int[arr.length];
for(int i: arr)
list1.add(i);
for(int i =0; i<arr.length; i++){
int minIndex = minimumPeakElement(list1);
output[i] = list1.get(minIndex);
list1.remove(minIndex);
}
return output;
}
public int minimumPeakElement(List<Integer> list1){
int minIndex = 0, peakStart = Integer.MAX_VALUE, peakEnd = Integer.MAX_VALUE;
int peak = Integer.MAX_VALUE, minPeak = Integer.MAX_VALUE;
if(list1.size() >= 2){
if(list1.get(0) > list1.get(1)) peakStart = list1.get(0);
if(list1.get(list1.size() - 1) > list1.get(list1.size() - 2)) peakEnd = list1.get(list1.size() - 1);
if(peakStart < peakEnd){
minPeak = peakStart;
minIndex = 0;
}
else if(peakEnd < peakStart){
minPeak = peakEnd;
minIndex = list1.size() - 1;
}
}
for(int i=1; i<list1.size() - 1; i++){
if(list1.get(i) > list1.get(i + 1) && list1.get(i) > list1.get(i-1)) peak = list1.get(i);
if(peak < minPeak){
minPeak = peak;
minIndex = i;
}
}
return minIndex;
}
Here is an idea how to optimize asymptotic complexity.
Use single pass over elements of your initial array to split it into "up-down" "slopes" or "hills", i.e. subsequence of elements in ascending order, followed by subsequence in descending order.
Store these slopes in the following datastructure:
val slopes = MinPriorityQueue<Slope>()
class Slope(
var first: Int, // first element of the slope
var last: Int, // last element of the slope
var peak: Int, // max or peak element
var els: MaxPriorityQueue<Int>(), // all elements of the slope
var prev: Slope?, // link to the previous slope in the list or null if first
var next: Slope? // link to the next slope in the list or null if last
)
Slopes should be comparable by their peak value.
Now, having this data structure, you can poll the slope that has minimal peak value in O(log(N)). After you polled the slope, you should update the slope by removing it's peak element (i.e. poll els, then update first, last, peak), also, slope might become eligible to be merged with the previous or next slope:
Admittedly, this solution is not an easy one, having a lot of things to maintain and large number of corner cases. However, it's much better in terms of asymptotic complexity.
Initial data structure build: O(n log(n))
Polling elements while maintaining slopes: O(n log (n))
Overall complexity: O(n log(n))
Notes:
One of the corner cases, if array can have duplicate elements, then inner priority queue (els) becomes MaxPriorityQueue<Pair<Int,Int>>, i.e. you need to store the number of potentially duplicate elements along with the element value.
MinPriorityQueue and MaxPriorityQueue is an abstract heap-based data structure with min and max element at the head respectively. Can be implemented with PriorityQueue in java

How can i print all possible order of an array with n integers using recursion?

For example, if I have an array a= {1, 2, 6, 10}, it should print all combinations of these 4 numbers, there should be 4! total combinations. An array of 5 integers will have a total of 5! combinations. (Different from previous versions because my number of parameters have to stay same. I am not allowed to put more than 3 paramrters in.
array a= {1, 2, 6, 10}
{1, 2, 10, 6}
{1, 6, 2, 10}
{1, 6, 10, 2}
.
.
.
{10, 6, 2, 1}
I am trying to solve this process using Recursion, any idea how? this is the code i have for now. Can anyone who has any idea whats going on please help me?
static void permutations (int a[], int n, int p){
if (p==n-1)
return ;
for (int i=p; i<n; i++){
int b[]=new int [n];
b[p]=a[i];
for (int j=0; j<i; j++)
b[j]=a[j];
for (int k =i+1; k<n; k++)
b[k]=a[k];
System.out.println(Arrays.toString(b));
return permutations(b, n, p+1);
}
}
best way to solve your problem to use Permutations concept in Algebra it's very useful way to get all possible combinations of a set.
you should also have knowledge in possibilities to solve this problem:
in this set {1, 2, 6, 10} element 1 has a k-Permutations which is 3
and this Permutations is : {2, 1, 6, 10},{6, 2, 1, 10},{10, 2, 6, 1}.
also element 2 has k-Permutations which is 2
2 Permutations is : {1, 6, 2, 10},{1, 10, 6, 2}.
element 6 has a k-Permutations which is 1
6 Permutations is : {1, 2, 10, 6}.
finally the total possible Permutations for all elements in set : 3 * 2 * 1 = 6.
simple algorithm to print all possible Permutations:
int[] num = {1,2,6,10};
int[] a = num.clone();
ArrayList<String> combs = new ArrayList<String>();
int temp;
for(int i=0; i < num.length-1; i++){
for(int j=i+1; j < num.length; j++){
temp = a[i];
a[i] = a[j];
a[j] = temp;
String obj = Arrays.toString(a);
if(!combs.contains(obj)){
combs.add(obj);
}
a = num.clone();
}
}
System.out.println("All possible order Combinations:");
for(String obj : combs){
System.out.println(obj);
}
output:
All possible order Combinations:
[2, 1, 6, 10]
[6, 2, 1, 10]
[10, 2, 6, 1]
[1, 6, 2, 10]
[1, 10, 6, 2]
[1, 2, 10, 6]
hope this would help.

Specifying random chance [duplicate]

This question already has answers here:
How to pick an item by its probability?
(13 answers)
Closed 8 years ago.
Now , I will generate random numbers between 1 to 5. I assume there has probability or chance to gain on each number . (please assume for example if you don't agree it)
1 has 20%
2 has 20%
3 has 20%
4 has 20%
5 has 20%
I would like to increase or decrease chances of some numbers as I wish..
1 has 10%
2 has 10%
3 has 35%
4 has 40%
5 has 5%
If so , I can generate random numbers as I wish. Some were hard to get and some will gain frequently.
How can I achieve it by Java ? Please support me with some examples or some useful links or anything else. I would really appreciated it. Please don't be suggest to describe some my efforted codes because I have no idea for this and I request some useful suggestions from you . Thanks in advance.
The solution is simple:
double r = random.nextDouble();
if (r < 0.1) ret = 1
else if (r < 0.2) ret = 2
else if (r < 0.55) ret = 3
...
you get the idea, use the cumulative likelihood as threshold.
First instantiate java.util.Random rand = new java.util.Random();. Do this exactly once.
From there, one approach is to use double f = rand.nextDouble(); which gives you a number between (and including) 0 to (and not including) 1.
Then transform using a series of ifs:
if (f < 0.1){
return 1;
} else if (f < 0.1 + 0.1){
return 2;
} else if (f < 0.1 + 0.1 + 0.35){
return 3;
... /*can you see the pattern*/
It's not quite the fastest way, but is clear and will get you started.
I don't know if there is a way with the Random library.
But I think you can generate a Random number between 1 and 100.
And so, you can code that between:
1 and 10 you obtain 1,
11 and 20 you obtain 2,
21 and 55 you obtain 3,
and so on
An alternative I can think about it is
int[] a = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 5, 5, 5, 5, 5};
Random r = new Random();
return a[ r.nextInt(100) ];

Categories