I am writing the code as shown at the bottom of this question.
For the while loop part, I thought the following two codes are just the same
first one
while (lIndex < rIndex && height[++lIndex] <= left) {
ans += (left - height[lIndex]);
}
second one
while (lIndex < rIndex && height[lIndex + 1] <= left) {
ans += (left - height[lIndex + 1]);
lIndex++;
}
However, when I run the second one on system,
There is an error of Time Limit Exceeding.
Could someone explain the reason of this problem?
Thanks for reading my question.
Original code:
public int trap(int[] height) {
if (height.length < 3) return 0;
int ans = 0;
int lIndex = 0;
int rIndex = height.length - 1;
// Find the first wall on each side
while (lIndex < rIndex && height[lIndex] <= height[lIndex + 1]) lIndex++;
while (lIndex < rIndex && height[rIndex] <= height[rIndex - 1]) rIndex--;
while (lIndex < rIndex) {
int left = height[lIndex];
int right = height[rIndex];
if (left <= right) {
while (lIndex < rIndex && height[++lIndex] <= left) {
ans += (left - height[lIndex]);
}
}
else {
while (lIndex < rIndex && height[--rIndex] <= right) {
ans += right - height[rIndex];
}
}
}
return ans;
}
In the first example, lIndex is incremented even when evaluation of the condition ends up with it being false. In other words, if the while loop body is executed n times, lIndex will be incremented n + 1 times.
In the second example, lIndex is only incremented with the rest of the body. So if the while loop body is executed n times, lIndex will be incremented n times.
Here's a very simple example of both, showing the difference:
public class Test {
public static void main(String[] args) {
int i = 0;
while (++i < 3) {
System.out.println("First loop iteration");
}
System.out.println("Value of i afterwards: " + i);
int j = 0;
while (j + 1 < 3) {
System.out.println("Second loop iteration");
j++;
}
System.out.println("Value of j afterwards: " + j);
}
}
Output:
First loop iteration
First loop iteration
Value of i afterwards: 3
Second loop iteration
Second loop iteration
Value of j afterwards: 2
So both loops execute the body twice, but they end up with different counter values.
This question already has answers here:
What is x after "x = x++"?
(18 answers)
Closed 3 years ago.
This is a part of my 2nd method.. the method is using the first and last values of an array given by my main method and adding them together. If the sum is above (in my example "20"), then j (the last value of the array) decreases. If the sum is below 20, i (first value of the array) is increased. The process is repeated until either i == j or i + j = 20
I am using a do ... while loop with a couple of if statements...but for some reason, my program keeps running and gives no result. Help?
public static int checkSum(int[] array){
int i = 0;
int j = 6;
int sum;
sum = array[i] + array[j];
do {
if (sum == 20) {
break;
}
else if (sum < 20) {
i = i++;
sum = array[i] + array[j];
}
else {
j = j--;
sum = array[i] + array[j];
System.out.print("No");
}
sum = array[i] + array[j];
} while (i != j);
if (i == j) {
i = -1;
}
return i;
For the sake of not spamming the website.. i should be 2... but my program gives no results and keeps running infinitely..
The reason your program keeps running is because you are never changing the values of i and j.
The syntax i++ means "increment i, but return the original value (BEFORE the increment)"
So, when your code has a statement like :
i = i++;
you are assigning i to be the value BEFORE the increment - ie. it's not changing !
The fix is to simply use i++ and j++ without assignments.
public static int checkSum(int[] array) {
int i = 0;
int j = 6;
int sum;
do {
sum = array[i] + array[j];
if (sum == 20) {
break;
} else if (sum < 20) {
i++;
} else {
j--;
}
} while (i != j);
if (i == j) {
i = -1;
}
return i;
}
Issue is how you use i++. Check this thread for more details
And I have removed unnecessary code parts mainly the sum = array[i] + array[j].
This solution of mine has 1 test failed.
https://app.codility.com/demo/results/trainingU5HYHS-MDC/
import java.util.Arrays;
class Solution {
public int solution(int[] A) {
// write your code in Java SE 8
if(A.length<3)
return 0;
Arrays.sort(A);
for(int i=0;i<A.length-2;i=i+1)
{
if( A[i]+A[i+1]>A[i+2] )
{
return 1;
}
}
return 0;
}
}
but this solution has passed 100% percent, but i cant understand why
https://app.codility.com/demo/results/trainingYKT8FB-TAV/
class Solution {
/**
* Check whether there is a triangular
* #param A The array for length of lines
* #return 0: no triangular found
* 1: triangular is found
*/
public int solution(int[] A) {
// Handle with the special cases
if(null == A || A.length < 3) return 0;
// Sort the input, and then try to find the triangular
Arrays.sort(A);
for(int i = 0; i < A.length-2; i++) {
// Beware of overflow
if (A[i] >= 0 && A[i] > A[i+2] - A[i+1]) {
return 1;
}
/*
* We already know A[i+1] <= A[i+2]. If A[i] < 0,
* A[i] + A[i+1] < A[i+2]
*/
}
return 0;
}
}
Your code fails when using 2 values that together are > than the maximum value an integer can be assigned to.
In the line if( A[i]+A[i+1]>A[i+2] ) you are making an addition. If this exceeds the integer limit you will run into an integer overflow.
The other code avoids this by never doing such an addition.
Inequality rule:
which states: the length of a side of a triangle is less than the sum of the lengths of the other two sides and greater than the difference of the lengths of the other two sides.
If we go through the sides a + b > c
if the sum of A[I] + A[I+1] larger than the capacity of int then it becomes a case of overflow, and the result of A[I] + A[I+1] < 0 => A[I] + A[I+1] not greater than A[I+2].
Here if( A[i]+A[i+1]>A[i+2] ) returns false when overflow occurs.
So, better to use,
if (A[i + 2] >= 0 && A[i + 2] > A[i + 1] - A[i])
or
if (A[i] >= 0 && A[i] > A[i+2] - A[i+1])
Basically I replaced n with aData[i] in the Non-working implementation. Am I missing something fundamentally wrong? The Second implementation fails on the same TEST Data.
Passing implementation:
static long[] sort(long[] aData) {
for (int i = 1; i < aData.length; i++) {
long n = aData[i];
int j = i - 1;
while (j >= 0 && aData[j] > n) {
aData[j + 1] = aData[j];
j--;
}
aData[j + 1] = n;
}
return aData;
}
Failing implementation:
static long[] sort(long[] aData) {
for (int i = 1; i < aData.length; i++) {
int j = i - 1;
while (j >= 0 && aData[j] > aData[i]) {
aData[j + 1] = aData[j];
j--;
}
aData[j + 1] = aData[i];
}
return aData;
}
In the first iteration of the while loop, j + 1 == i. So when you write aData[j + 1] = aData[j], you change the value of aData[i] within the loop.
In the initial version, n is constant throughout the operation. Also note that using aData[i] instead of n is very unlikely to improve performance (if anything, it will probably be slower).
This question already has an answer here:
How can I locate an index given the following constraints? [closed]
(1 answer)
Closed 9 years ago.
Given an array of n integers A[0…n−1], such that ∀i,0≤i≤n, we have that |A[i]−A[i+1]|≤1, and if A[0]=x, A[n−1]=y, we have that x<y. Locate the index j such that A[j]=z, for a given value of z, x≤ z ≤y
I dont understand the problem. I've been stuck on it for 4 days. Any idea of how to approach it with binary search, exponential search or interpolation search recursively? We are given an element z find the index j such that a [j] = z (a j) am i right?.
static int binarySearch(int[] searchArray, int x) {
int start, end, midPt;
start = 0;
end = searchArray.length - 1;
while (start <= end) {
midPt = (start + end) / 2;
if (searchArray[midPt] == x) {
return midPt;
} else if (searchArray[midPt] < x) {
start = midPt + 1;
} else {
end = midPt - 1;
}
}
return -1;
}
You can use the basic binary search algorithm. The fact that A[i] and A[i+1] differ by at most 1 guarantees you will find a match.
Pseudocode:
search(A, z):
start := 0
end := A.length - 1
while start < end:
x = A[start]
y = A[end]
mid := (start+end)/2
if x <= z <= A[mid]:
end := mid
else if A[mid] < z <= y
start := mid + 1
return start
Note that this doesn't necessarily return the first match, but that wasn't required.
to apply your algorithms your need a sorted array.
the condition of you problem says that you have an array which has elements that differ with max 1, not necessarily sorted!!!
so, here are the steps to write the code :
check if problem data respects given conditions
sort input array + saving old indexes values, so later can can initial positions of elements
implement you search methods in recursive way
Binary search source
Interpolation search source
Here's full example source :
public class Test {
// given start ======================================================
public int[] A = new int[] { 1, 1, 2, 3, 4, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6,
7, 8 };
public int z = 4;
// given end =======================================================
public int[] indexes = new int[A.length];
public static void main(String[] args) throws Exception {
Test test = new Test();
if (test.z < test.A[0] || test.z > test.A[test.A.length - 1]){
System.out.println("Value z="+test.z+" can't be within given array");
return;
}
sort(test.A, test.indexes);
int index = binSearch(test.A, 0, test.A.length, test.z);
if (index > -1) {
System.out.println("Binary search result index =\t"
+ test.indexes[index]);
}
index = interpolationSearch(test.A, test.z, 0, test.A.length-1);
if (index > -1) {
System.out.println("Binary search result index =\t"
+ test.indexes[index]);
}
}
public static void sort(int[] a, int[] b) {
for (int i = 0; i < a.length; i++)
b[i] = i;
boolean notSorted = true;
while (notSorted) {
notSorted = false;
for (int i = 0; i < a.length - 1; i++) {
if (a[i] > a[i + 1]) {
int aux = a[i];
a[i] = a[i + 1];
a[i + 1] = aux;
aux = b[i];
b[i] = b[i + 1];
b[i + 1] = aux;
notSorted = true;
}
}
}
}
public static int binSearch(int[] a, int imin, int imax, int key) {
// test if array is empty
if (imax < imin)
// set is empty, so return value showing not found
return -1;
else {
// calculate midpoint to cut set in half
int imid = (imin + imax) / 2;
// three-way comparison
if (a[imid] > key)
// key is in lower subset
return binSearch(a, imin, imid - 1, key);
else if (a[imid] < key)
// key is in upper subset
return binSearch(a, imid + 1, imax, key);
else
// key has been found
return imid;
}
}
public static int interpolationSearch(int[] sortedArray, int toFind, int low,
int high) {
if (sortedArray[low] == toFind)
return low;
// Returns index of toFind in sortedArray, or -1 if not found
int mid;
if (sortedArray[low] <= toFind && sortedArray[high] >= toFind) {
mid = low + ((toFind - sortedArray[low]) * (high - low))
/ (sortedArray[high] - sortedArray[low]); // out of range is
// possible here
if (sortedArray[mid] < toFind)
low = mid + 1;
else if (sortedArray[mid] > toFind)
// Repetition of the comparison code is forced by syntax
// limitations.
high = mid - 1;
else
return mid;
return interpolationSearch(sortedArray, toFind, low, high);
} else {
return -1;
}
}
}