What is this algorithm doing? - java

I got a pseudocode:
Input: Array A with n (= length) >= 2
Output: x
x = 0;
for i = 1 to n do
for j = i+1 to n do
if x < |A[i] - A[j]| then
x = |A[i] - A[j]|;
end if
end for
end for
return x;
I have converted that to a real code to see better what it does:
public class Test
{
public static void main (String[] args)
{
int A[] = {1,2,3,4,5,6,7,8,9};
int x = 0;
for (int i = 1; i < A.length; i++)
{
for (int j = i + 1; j < A.length; j++)
{
if (x < Math.abs(A[i] - A[j]))
{
x = Math.abs(A[i] - A[j]);
}
}
}
System.out.println(x);
}
}
The output was 7 with the array in the code.
I have used another array (1 to 20) and the putput was 18.
Array 1-30, the output was 28.
The pattern seems clear, the algorithm gives you the antepenultimate / third from last array value. Or am I wrong?

I think the pseudo code tries to find the greater of the difference between any 2 elements within an array.
Your real code however, starts from 1 instead of 0 and therefore excludes the first element within this array.

I think pseudocode is trying to find the greatest difference between two numbers in an array. It should be the difference between the minimum and maximum value of the array.
I personally think this is a really poor algorithm since it is doing this task in O(n^2). You can find the min and maximum value of an array in O(n). and take the difference between those numbers and result will be the same. check the pseudocode
Input: Array A with n (= length) >= 2
min=A[0];max = A[0];
for i = 1 to n do
if min > A[i] then
min = A[i];
end if
if max < A[i] then
max = A[i]
end if
end for
return (max-min);

The code gives the biggest difference between any two elements in the array.
There are 2 nested loops, each running over each element of the array. The second loop starts at the element after the first loop's element, so that each possible pair is considered only once.
The variable x is the current maximum, initialized to 0. If x is less than the absolute value of the current pair's difference, then we have a new maximum and it is stored.
However, because you directly copied the pseudocode's starting index of 1, you are inadvertently skipping the first element of the array, with index 0. So your Java code is giving you the maximum difference without considering the first element.
If you have an array of values between 1 and n, you are skipping the 1 (in index 0) and the returned value is n - 2, which happens to be the third-to-last value in the array. If you had shuffled the values in the array as a different test case, then you would see that the returned value would have changed to n - 1 as now both 1 and n would be considered (as long as n itself wasn't in the first position).
In any case, you would need to set the index of the first element to 0 so that the first element is considered. Then {1,2,3,4,5,6,7,8,9} would yield 8 (or any other order of those same elements).

Assuming all positive integers, the algorithm in a nutshell finds the difference between the maximum and the minimum value in the array. However, it will not work correctly unless you initialize i to 0 in the for loop.
for (int i = 0; i < A.length; i++)

Related

How to determine the best postcondition in this question?

Consider the following program segment:
/** Precondition: a[0]...a[n-1] is an initialized array of integers, and 0 < n <= a.length. **/
int c = 0;
for (int i = 0; i < n; i++)
if (a[i] >= 0)
{
a[c] = a[i];
c++;
}
n = c;
Which is the best postcondition for the segment?
a[0] to a[n-1] has been stripped of all positive integers.
a[0] to a[n-1] has been stripped of all negative integers.
a[0] to a[n-1] has been stripped of all nonnegative integers.
4a[0] to a[n-1] has been stripped of all occurrences of zero.
The updated value of n is less than or equal to the value of n before execution
of the segment.
This is a question on the AP CSA exam. The answer key says that 2. is the answer (it states that 5. is also correct but would not be the "best" postcondition). But I am just thinking: "what if ALL the elements in the initial list are negative numbers?" If that's the case, wouldn't it be impossible to strip away any negative number?
"what if ALL the elements in the initial list are negative numbers?" If that's the case, wouldn't it be impossible to strip away any negative number?
I thought so too at first, but note that the end n is updated:
n = c
With that and only negative numbers n would be zero and a[0] to a[n-1] would be an empty set, for which the statement It does not contain negative numbers is true.
Note, that the algorithm is changing the array's values in place, so it really "strips away" negative numbers. It does it by iterating through all elements of array a and moving it to a lower index if it's a non-negative number.
Then at the end, it sets n to the last index of the element which met the criteria (being non-negative). That's why you have n = c; as the last statement.
So statement 2 is true. The new size of the array is always smaller or equal to the original, so statement 5 is also true.
One thing to notice: In Java, you can still reach all elements if you iterate through the original array. Because in Java every array has a fixed length since being initialized. Let's see the following array:
int a[] = {-1,2,3,-4,5,-6,7,8,-9,-10};
So if I iterate using n at the end, I just get the values that meet the criteria:
for (int i = 0; i < n; i++) {
System.out.print(a[i] + ",");
}
This will print 2,3,5,7,8, but if I iterate through a I get all the values from the end of the array:
for (int e : a) {
System.out.print(e + ",");
}
Now it will print 2,3,5,7,8,-6,7,8,-9,-10. So this algorithm leaves some garbage behind.

How to check index of integer array element in java? [duplicate]

This question already has answers here:
How to find the index of an element in an array in Java?
(15 answers)
Closed 6 years ago.
In the below code I can get the length and element of array. if I have to check what is the index number at run time for every element, how can I check that?
If I print the value of i from loop every time with the array element it will give the same value, will that be correct to consider the value of i as index value of array?
Another confusion in during the debug in eclipse it shows id value of array is different than the loop value.
public class FirstArray {
public static void main(String[] args) {
int[] arr = {11,12,13,14,15,16,17,18,19,20};
int onelength = arr.length;
System.out.println("Size of Array is: " + onelength);
for(int i = 0; i < arr.length; i++){
System.out.println("element of aray is: "+ arr[i]);
}
}
}
Yes, value of i will be the index value. I would suggest you to go through basics of Java arrays.
The question itself is not clear. The loop bounds are definitely different from the index value of the array. If you want to print the loop bounds along with the value at the index, just print i in the loop.
For your question "what is the index number at run time for every element, how can i check that?" Refer to the solution bellow:
Where is Java's Array indexOf?
For your question "If i print the value of i from loop every time with the array element it will give the same value, will that be correct to consider the value of i as index value of array?"
The array index starts from 0, so if your array length is 10 then index values will be 0 to 9. Thus, if you start your loop from i=0 then the index value will be same as i, but if you start your loop from i=1 then the index value will be i-1.
Will that be correct to consider the value of i as index value of
array?
Of course it'll be correct, i is actually the index of the array.
Another confusion in during the debug in eclipse it shows id value of
array is different than the loop value
Yes, it shows because it's really different, take a look:
for(int i = 0; i < arr.length; i++) {
System.out.println("element of aray is "+ arr[i]); // It prints the element itself -> 11 12 13 14 15.. and so on
System.out.println("iteration number "+ i); // It prints the index of iteration -> 0 1 2 3 4 5.. and so on
}
You may want to clarify what exactly you are searching for.
An array stores a value at a given index (starting at index zero, and going up to index length-of-the-array-minus-one).
The traditional way of creating an array is the following:
// Create an empty array that is able to hold 3 values
int[] numbers = new int[3];
numbers[0] = 11;
numbers[1] = 15;
numbers[2] = 13;
If we now print the values in the index order, we receive 11, 15 and 13. Here's the code:
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
So, we see with numbers[i] = 14 we can assign the value 14 to the index i of the array. And with System.out.println(numbers[i]), we can print the value the array has stored at index i.
An array has a fixed length which needs to be specified at creation, it is not a flexible data structure (but pretty fast and small). Thus, if you are trying to access numbers[100] but we said numbers can only hold 3 values, then you will get an ArrayIndexOutOfBoundsException.
Your provided code is a short-hand for the traditional way:
int[] arr = {11,12,13};
which does the same as
int[] arr = new int[3];
arr[0] = 11;
arr[1] = 12;
arr[2] = 13;
If you want to search for the index, given the value (assuming the values are unique), you need to search the whole array until you find the index. Here's some code:
public int getIndex(final int[] array, final int value) {
for (int i = 0; i < array.length; i++) {
if (array[i] == value) {
// Value found
return i;
}
}
// Value not found
return -1;
}
Note that the search code is pretty slow, because you may need to search the whole length of the array (worst case). Other data structures may be more useful depending on your usage.

Finding the missing number in an array with nested for loops in Java

I need to find the missing number in an array in O(n^2) time. I can rearrenge the array, so it is in order, but I have a difficult time finding the missing number without running another for loop, but I can't do that.
Here is my code:
The missing number is 3 here.
public static void main(String[] args){
int ar []={0,1,6,2,5,7,4};
int n = ar.length;
int temp = 0;
int m = 0;
for(int i = 0; i<n;i++){
for(int j = 1; j<n;j++){
if(ar[j-1] > ar[j]){
temp = ar[j-1];
ar[j-1]=ar[j];
ar[j]=temp;
if(ar[j-1]!=j-1) m=j;
}
else ar[j]=ar[j];
if(ar[j-1]!=j-1) m=j;
}
}
System.out.println(m);
}
If the input array contains all the numbers between 0 and ar.length except one missing number (as in your {0,1,6,2,5,7,4} example), you can find the missing number in linear time.
Just calculate the sum of all the numbers of the full array (the one including the missing number) - that array has ar.length + 1 elements from 0 to ar.length, so its sum is (ar.length - 0)*(ar.length + 1)/2 - and subtract from it the actual sum (which you can compute in a simple linear time loop). The difference would be the missing number.
If there are multiple missing numbers (or there may be duplicate numbers), and you need to find the first missing number, sorting the array in O(n*log(n) time and then making a single (linear time) pass over the sorted array would still be better than an O(n^2) solution.
If you can only do 2 loops, and must do 2 loops for O(n^2), then I suggest the following:
Loop thru all values (outer loop).
For each value, loop thru all values (inner loop) and find smallest value higher than current value.
If no higher value found, skip (current value is highest value)
If smallest value found is not current value + 1, then you found the missing value
How about this?
int array[] = {0,1,6,2,5,7,4};
int arrayTemp[] = array;
ArrayList<Integer> missing = new ArrayList();
Arrays.sort(arrayTemp);
for (int i=1; i<arrayTemp.length; i++) {
for (int j=arrayTemp[i-1]+1; j<arrayTemp[i]; j++) {
missing.add(j);
}
}
for (int i=arrayTemp[arrayTemp.length-1]+1; i<=arrayTemp[arrayTemp.length-1]; i++) {
missing.add(i);
}
System.out.println(missing.toString());
Output:
{0,1,6,2,5,7,4} -> [3]
{0,1,6,2,5,7,4,14} -> [3, 8, 9, 10, 11, 12, 13]

Testing elements in an array

Hello I have searched for a simple way to check ,
if any number of elements up to 6 in the array add up to seven. I have yet to find one my array is this,
private int[] diceRoll = new int[6];
The question is a bit vague, however, here's my attempt at an answer:
If what you're trying to do is take two indices x and y in diceRoll[] and see if they add up to 7, the simplest thing to do is
if(diceRoll[x] + diceRoll[y] ==7){
return true;}
If you're trying to see if ANY item with any other item adds up to 7, use a double for-loop (these are weird, but very helpful)
for(int i = 0; i < diceRoll.length; i++){
for(int j = 0; i < diceRoll.length; i++){
if(diceRoll[i] + diceRoll[j] != 7){
return false;
}
}
}
Hope this helps!
-katie
It sounds like what you need to do is take every subset of the diceRoll array and see which ones add up to 7. This is how it can be done.
Assuming you know that 1 & 1 = 1, and that 1 & 0 = 0, imagine each element of the array having a number in 0 0 0 0 0, if the element is selected, say element 5, the subset representation in binary form would be 0 0 0 0 1. If element 2 and 3 are selected, the subset representation would be 0 0 1 1 0. If you take a binary one, keep track of its index, and move it from right to left in the array computing index&1 each time, you can get which indexes of the array are in the current subset (if the index&1 computation results in a 1 for that index). Translating this to a smaller array called currSubset, you can sum it up and check if it is equal to 7.
The termination of the outer for loop comes from the maximum value of a 5 digit binary number, which is 11111 = 31 = 2^5-1, hence the use of the less than sign.
int sum = 0;
int index = 0;
ArrayList<ArrayList<Integer>> subsetsThatAddTo7 = new ArrayList<ArrayList<Integer>>();
for(int subsetRep = 0b00001; i < Math.pow(2,5); i++){
ArrayList<Integer> currSubset = new ArrayList<Integer>
for(index = 0; index < 5; index++){
if(subsetRep & (1 << index))
currSubset.add(diceRoll[5-index]);
}
int sum = 0;
for(int num : currSubset)
sum += num;
if(sum == 7)
subsetsThatAddTo7.add(currSubset);
}

What is wrong with my Java solution to Codility MissingInteger? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I am trying to solve the codility MissingInteger problem link:
Write a function:
class Solution { public int solution(int[] A); }
that, given a non-empty zero-indexed array A of N integers, returns the minimal positive integer that does not occur in A.
For example, given:
A[0] = 1
A[1] = 3
A[2] = 6
A[3] = 4
A[4] = 1
A[5] = 2
the function should return 5.
Assume that:
N is an integer within the range [1..100,000];
each element of array A is an integer within the range [−2,147,483,648..2,147,483,647].
Complexity:
expected worst-case time complexity is O(N);
expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.
My solution is:
class Solution {
TreeMap<Integer,Object> all = new TreeMap<Integer,Object>();
public int solution(int[] A) {
for(int i=0; i<A.length; i++)
all.put(i+1,new Object());
for(int i=0; i<A.length; i++)
if(all.containsKey(A[i]))
all.remove(A[i]);
Iterator notOccur = all.keySet().iterator();
if(notOccur.hasNext())
return (int)notOccur.next();
return 1;
}
}
The test result is:
Can anyone explain me why I got this two wrong answers? Especially the first one, if there is only one element in the array, shouldn't the only right answer be 1?
Here is my answer, got 100/100.
import java.util.HashSet;
class Solution {
public int solution(int[] A) {
int num = 1;
HashSet<Integer> hset = new HashSet<Integer>();
for (int i = 0 ; i < A.length; i++) {
hset.add(A[i]);
}
while (hset.contains(num)) {
num++;
}
return num;
}
}
returns the minimal positive integer that does not occur in A.
So in an array with only one element, if that number is 1, you should return 2. If not, you should return 1.
I think you're probably misunderstanding the requirements a little. Your code is creating keys in a map based on the indexes of the given array, and then removing keys based on the values it finds there. This problem shouldn't have anything to do with the array's indexes: it should simply return the lowest possible positive integer that isn't a value in the given array.
So, for example, if you iterate from 1 to Integer.MAX_VALUE, inclusive, and return the first value that isn't in the given array, that would produce the correct answers. You'll need to figure out what data structures to use, to ensure that your solution scales at O(n).
I have done the answer inspired by the answer of Denes but a simpler one.
int counter[] = new int[A.length];
// Count the items, only the positive numbers
for (int i = 0; i < A.length; i++)
if (A[i] > 0 && A[i] <= A.length)
counter[A[i] - 1]++;
// Return the first number that has count 0
for (int i = 0; i < counter.length; i++)
if (counter[i] == 0)
return i + 1;
// If no number has count 0, then that means all number in the sequence
// appears so the next number not appearing is in next number after the
// sequence.
return A.length + 1;
returns the minimal positive integer that does not occur in A
The key here is that zero is not included in the above (as it is not positive integer). So the function should never return 0. I believe this covers both of your failed cases above.
edit: due to the fact that question has been changed since this was written this answer isn't really relevant anymore
Very little wrong.
Just the last line
return 1;
should read
return A.length + 1;
because at this point you've found & removed ALL KEYS from 1 to A.length since you have array entries matching each of them. The test demands that in this situation you must return the next integer above the greatest value found in array A.
All other eventualities (e.g. negative entries, missing 1, missing number between 1 and A.length) are covered by returning the first unremoved key found under iteration. Iteration here is done by "natural ordering", i.e. 1 .. max, by default for a TreeMap. The first unremoved key will therefore be the smallest missing integer.
This change should make the 2 incorrect tests okay again. So 50/50 for correctness.
Efficiency, of course, is another matter and one that carries another 50 points.
Your use of the TreeMap data structure here brings a time penalty when evaluating the test results. Simpler data structures (that essentially use your algorithm) would be faster.
This more primitive algorithm avoids sorting and copies all entries > 1 onto a new array of length 100001 so that index x holds value x. It actually runs faster than Serdar's code with medium and large input arrays.
public int solution(int[] A)
{
int i = 0,
count = 0,
N = A.length;
int[] B = new int[100001]; // Initially all entries are zero
for (i = 0; i < N; i++) // Copy all entries > 0 into array B ...
{
if (A[i] > 0 && A[i] < 100001)
{
B[A[i]] = A[i]; // ... putting value x at index x in B ...
count++; // ... and keep a count of positives
}
}
for (i = 1; i < count + 1; i++) // Find first empty element in B
{
if (B[i] == 0)
{
return i; // Index of empty element = missing int
}
}
// No unfilled B elements above index 0 ?
return count + 1; // => return int above highest filled element
}

Categories