I ve got an issue with the ArrayIndexOutofBound error when trying to determine whether data is heap following the 2i + 1/2 formula child-parent relationship. Do you know how can I resolve the issue?
for (int i = 0; i < array.length; i++)
{
if ((array[i] < array[2*i + 1]) || (array[i] < array[2*i + 2]))
{
bool = false;
....
}
}
I would suggest checking for the boundaries of the array first, and if it contains enough elements, then you can compare them:
if ((array.length >= 2*i + 2)
&& ((array[i] < array[2*i + 1]) || (array[i] < array[2*i + 2])))
{
bool = false;
....
}
Your for-loop guard allows i == array.length -1. But inside the loop, you look for element 2 * i + 2. That's 2 * array.length. That's way beyond the end of the array, and will always throw an excpetion (except when i == 0).
Change your for-loop guard to i < ((array.length / 2) - 1), so that the maximal value of 2 * i + 2 is array.length - 1. Also, ensure you test this both for arrays of even and odd length; I think the logic will work in only one case.
Related
that, given a non-empty zero-indexed array A of N integers, returns the minimal positive integer (greater than 0) that does not occur in A. For example, given:
A[0] = 4
A[1] = 6
A[2] = 2
A[3] = 2
A[4] = 6
A[5] = 6
A[6] = 1
the function should return 4. Assume that:
in other words, A[K] = 2 for each K (0 <= K <= 50000), the given implementation works too slow, but the function would return 50,000
Write an efficient algorithm for the following assumptions:
N is an integer within the range [1...100,000]
each element of array A is an integer the range [1..N]
My Answer is not yet successful! What is wrong with it? First let me state the obvious errors
return value - I return 4 in the first result and that was successful
but the second return is 1 that is not correct for the reason that
the expected result is 50,000
my code, which works but the only first result is correct and second is not.
import java.util.*;
class Solution {
int solution(int[] A) {
int[] AN = Arrays.stream(A).filter(n -> n > 0).distinct().sorted().toArray();
int N = AN.length;
int min = 1;
int i = 0;
while (i < N) {
min = i+1;
if (min == N) {
min = Math.max(min , Math.abs(i-N));
}
i++;
}
return min;
}
}
Note: In the example you gave, the missing integer is 3 and not 4
The performance issue is probably caused by using the distinct and sorted.
I'll create an algorithm based on the sorted array, so its complexity is O(n log n).
First we sort the array:
Arrays.sort(A);
Next we skip negative or zero numbers
while (i < A.length && A[i] <= 0)
i++;
If now the array is fully parsed or the current element A[i] is not 1, then the solution is 1.
If it's not the case, we continue parsing the array A, we initiliase missing variable to 1 and if the current element equals the missing element we increment i, or if the current element is equal missing + 1 we increment missing otherwise we stop, we found our missing integer.
In the end if our array is fully parsed without any mismatch between missing variable and A[i] then we increment missing.
The full code:
Arrays.sort(A);
int missing = 1;
int i = 0;
while (i < A.length && A[i] <= 0)
i++;
if (i < A.length && A[i] == 1) {
while (i < A.length) {
if (A[i] == missing) {
i++;
} else if (A[i] == missing + 1) {
missing++;
} else {
missing++;
break;
}
}
missing = i >= A.length ? missing + 1 : missing;
}
System.out.println(missing);
I'm writing an algorithm that compares a number n with elements n+1 and n-1.
This means that the first and last check fail because array.length + 1 would be out of bounds and so would array[0-1]. I'm trying to find a way to stop the program from throwing the array index out of bounds exceptions but I am not sure how to do this. My initial plan was to check that array[0-1] and length+1 are always null like so:
numbers[x-1] == null
But this doesn't work because of a mismatch from int to null. Any ideas on how to remedy this would be very appreciated.
Iteration starts with index 1 and ends with index array.length - 1.
for(int i=1;i<array.length-1;i++){
int prev = array[i-1];
int current = array[i];
int next = array[i+1];
}
I'd just a checks for the edges of the array :
int prev = -1;
int next = -1;
for (int i=0; i<array.length; i++) {
if (i>0)
prev = array[i-1];
if (i < array.length - 1)
next = array[i+1];
else
next = -1;
// now do whatever you wish to do with array[i], prev and next
}
In that case I chose -1 to represent a "null" value. You can use something else, depending on the range of the values that can be in your array.
You should use "if" statements to check that your index is within the bounds:
if (x >= 0 && x < numbers.length)
numbers[x] = someNumber
Besides the length checks the other answers suggest, you also could create the array one element bigger, so that the last element n+1 is still a valid array position but marks the end of the array. This way you can forget all the length checks which would improve the speed of your algorithm - if this is important. Otherwise I would implement a length check.
Something you could use to compare arrays with last and next element:
for(int index=1;index<array.length-1;index++){
if (number > numbers[index - 1] && number < numbers[index + 1]) {
System.out.println("Number is between " + (index - 1) + " and " + (index + 1));
}
}
I understand that arrays are used to store values but when they are used with for loops I loose track of what is happening. I know that the output is 100 because I ran it in the terminal but what I need to understand is that how did it get 100 from using the for loops and the arrays because I'm not sure if it uses all three values or just the first one. Thanks in advance
Here is the problem:
public class arrays {
public static void main (String[] args) {
int[] a1 = {1, 1, 3};
mystery(a1);
}
public static void mystery(int[] a) {
for (int i = 1; i < a.length - 1; i++) {
a[i] = (a[i - 1] + a[i + 1]) /2;
}
}
}
Not entirely sure what the question you're trying to ask is but - to try and help - does it help that each time a[i] is called, it takes the value of i (also the iteration number) at each instance and uses that to find the relevant array index - which is then used for the rest of the computation.
try to add this method for tracing.
public class arrays{
public static void main(String[] args) {
int[] a1 = {1, 1, 3};
mystery(a1);
}
public static void mystery(int[] a) {
for (int i = 1; i < a.length - 1; i++) {
a[i] = (a[i - 1] + a[i + 1]) /2;
printArray(a);
}
public void printArray(int[] arr){
for(int i=0;i<arr.length;i++){
System.out.println("array[" + i + "] is now " + arr[i]);
}
}
EDIT: So what's going on back-stage?
for loop initializes i as 1.
a[1] (previously '1') is changed into (a[0] + a[2])/2 = (1 + 3)/2 = 2)
i is incremented by 1
i does not meet the condition (i < a.length - 1) because i = 2 and (a.length - 1) = (3 - 1) = 2 (2 is not less than 2, its equal to 2)
loop terminates and so is the program.
I think what you're missing is that i does not represent the index of the number 1 in your array, it is the index itself when used in the context of a[i] meaning "go to a, in index i..."
Your question is not clear. If you can provide question clearly, you will get great answers ! Anyways :
Try to think yourself.
Array position starts from "0" which is also called as the index of the array.
Here loop is going from value of
i =1 to i < the value of (array's length)-1 which is i < 2 as length of array = 3
So,
for(int i=1 ; i < a.length - 1; i++){
a[i] = (a[i - 1] + a[i + 1]) /2;
}
Now take initially value of i=1 and then run the code yourself in your mind :
1.. for i = 1,
**a[i] = (a[i - 1] + a[i + 1]) /2;**
gives a[1] = (a[0] + a[2])/2 ==> a[1] = (1+3)/2 ==> a[1] = 2
Important : you have given **i < a.length-1**
Now, a.length = 3 ok?
a.length -1 = 2 ok?
so i< a.length-1 will stop at i equals 1
So, your program will give {1,2,3} as for loop will iterate from i =1 to i=1 got it?
So only 1 value i.e. a[1] will gets changed.. a[0] and a[2] will remain same.
What happens when the method mistery(a1) is called:
1. int i is initialized to 1
2. The condition if i*a.length-1, which is (3-1), is checked; this condition is true;
3. because the condition at 2. is true, the code in the for loop is executed:
a[i] = (a[i - 1] + a[i + 1]) /2 => a[1] = (a[1-1]+a[1+1])/2 => a[1]=(a[0]+a[2])/2 =>
=> a[1]=(1+3)/2 => a[1]=2
4. after the code in the for loop is executed, i is incremented by 1, thus, the final stage of this for loop is executed: i++, i is equal to 2 right now.
5. Again, the for loop checks if the condition i<a.length-1, (3-1) is true; this time, the condition is false: i=2, 2 is not less than 2.
6. The for loop terminates its "existence", in this case the method mystery(a1) is fully executed.
What is the best way to check if a string index is in bounds? Let's say we are checking a String for index i-1 or i+1 because you cannot say != null.
Example:
for (int i = 0; i < string.length(); i++)
{
if (string.charAt(i+1) == '#' && string.charAt(i - 1) != '1')
{
}
}
Should you just check the length of the string and see if it is within it?
string.charAt(i+1) == '#'
Yes, I think you need to make sure i+1 is not greater than String length.
Example:
if( (i+1) < string.length() && (i-1) >= 0 && (yourcode))
{
}
Why not just check the length of the string?
if(myString.length() - 1 > i)
I've always modified the length (and/or start) of the loop in these cases... these are all good answers - there's no one way to do it, but this is how I would do it:
for (int i = 1; i < string.length() - 1; i++)
{
if (string.charAt(i+1) == '#' && (i != 1 || string.charAt(i - 1) != '1'))
{
}
}
EDIT: After considering all of the situations that this code entails, I wouldn't necessarily do this in this manner, but find a cleaner way to express exactly what I'm trying to accomplish
The simplest way is to change your for loop like this:
for (int i = 1; i < string.length() - 1; i++)
{
if (string.charAt(i+1) == '#' && string.charAt(i - 1) != '1')
{
}
}
Explanation:
string.charAt(i - 1) implies that you might read position i-1 of the string. Since 0 is the lowest valid value you can start the iteration with i = 1
string.charAt(i + 1) implies that you might read position i+1 of the string. Since string.length() - 1 is the highest valid value you need to end your iteration at i == string.length() - 2. Since the for-loop checks the condition before entering the loop using i < string.length() - 1 will be just right.
I would try with this code.
for (int i = 1; string!= null && string.length() >= 3 && i < string.length() - 1; i++)
//it solve the case of String == null and string too short
//it optimize the max number of cycles
{
if (string.charAt(i+1) == '#' && string.charAt(i - 1) != '1')
{
}
}
Suppose you have a sorted List containing server names. You'd like to collapse them as tightly as possible.
Example:
abcd01c, abcd02c, abcd04c, abcd05, z1x
should become
abcd0[1-4]c,abcd05,z1x
What is the simplest algorithm to take care of something like this?
I would store all strings in a prefix map, which makes the decision of a String exists very easy, and also allows fast iteration of a subset of Strings.
Store the Strings as:
(0)abcd01c
(5) 2c,
(5) 4c,
(4) 05,
(0)z1x
The number is the count of characters which have to be taken from the previous String. This is a common implementation for dictionaries like phonebooks, where you have to store many similar Strings.
A Trie is a similar structure, as Brian Roach noticed in the comments.
I'm a little shaky on what your actual need is, but an approach to this would be in a custom Trie (Wikipedia Entry)
When you reached the point in your key where your next character isn't an alpha character, you'd know that you had a prefix. Inside that node in the Trie you could then have another map (not pointing at additional Trie nodes) that was keyed by the suffix and contained the ranges for each.
You still have the problem, however, of the specific rules around your data. If you have abcd01c as the key, is the prefix abcd or abcd0?
I think dynamic programming can help. The shortest length can be computed for all sets of first elements of given array, i.e. {1}, {1,2}, {1,2,3}... Those numbers are computed consequently, so previous ones are used to calculate the current number. If we want to calculate A[i] and A[j] is known (j < i) and numbers from given array from j+1 to i can be compressed, then A[i] equals A[j] + length of compressed data.
upd
I hardly understand how to compress if range is set for more then one symbol. So, here is a simple realization in case of one symbol.
int prevIdx = -1;
int count = 0;
for (int i = 1; i < list.Length; i++) {
bool ok = true;
if (list[i].Length == list[i - 1].Length) {
int count = 0;
for (int j = 0; j < list[i].Length; j++)
if (list[i][j] != list[i - 1][j])
curIdx = j;
count++;
}
if (count > 1)
ok = false;
}
else
ok = false;
if (ok) {
if (prevIdx == curIdx) {
count++;
}
else {
prevIdx = curIdx;
if (count > 1)
answer.Add(list[i - 1].SubString(0, prevIdx - 1) +
'[' + count.ToString() + ']' + list[i - 1].SubString(prevIdx + 1, list[i - 1].Length);
else
answer.Add(list[i - 1]);
count = 0;
}
}
else {
if (count > 1)
answer.Add(list[i - 1].SubString(0, prevIdx - 1) +
'[' + count.ToString() + ']' + list[i - 1].SubString(prevIdx + 1, list[i - 1].Length);
else
answer.Add(list[i - 1]);
prevIdx = -1;
}
}
if (count > 1)
answer.Add(list[List.Length - 1].SubString(0, prevIdx - 1) +
'[' + count.ToString() + ']' + list[i - 1].SubString(prevIdx + 1, list[List.Length - 1].Length);
else
answer.Add(list[list.Length - 1]);