Is there a quicker way to increment a counter or break from an outer loop?
while(myArrayList.get(i) > myNumber) {
// some operations
if(i + 1 < myArrayList.size())
i++;
else
break;
}
A better way to write your code is definitely there:
for (int i = 0; i < myArrayList.size(); i++) {
if (myArrayList.get(i) <= myNumber) break;
//Some operations...
}
You need to check the size first to avoid running off the end of the list and getting an error.
int i;
for (i = 0; i < myArrayList.size(); i++)
if (myArrayList.get(i) <= myNumber)
break;
With the Streams API you could do
int n = IntStream.range(0, myArrayList.size())
.filter(i -> myArrayList.get(i) <= myNumber)
.findFirst()
.orElse(myArrayList.size()); // or -1
A for-loop is more appropriate here:
int counter = 0
for(int i = 0; i < myArrayList.size(); i++) {
if(!(myArrayList.get(i) > myNumber)) {
break;
}
counter++;
}
If the intention is count values that are greater than myNumber, then break will possibly exclude some values (unless you know that myArrayList is sorted), and the loop should rather be:
for(int i = 0; i < myArrayList.size(); i++) {
if(myArrayList.get(i) > myNumber) {
counter++;
}
}
I think you want to start counting from some index i,
int count=0;
for( ;((i < myArrayList.size()-1) && (myArrayList.get(i) > myNumber));i++){
count++;
}
Related
I'm practicing coding on HackerRank, and I have the following code, which gets a different outputs.
The task is the following:
Given an array of integers, find the longest subarray where the absolute difference between any two elements is less than or equal to.
Example:
a = [1,1,2,2,4,4,5,5,5];
There are two subarrays meeting the criterion: [1,1,2,2] and [4,4,5,5,5]. The maximum length subarray has 5 elements.
The following code gets the desired output:
public static int pickingNumbers(List<Integer> a) {
// Write your code here
int max = 0;
int counter = 0;
Collections.sort(a);
for(int i = 0; i < a.size(); i++){
for(int j = i+1; j< a.size(); j++){
if(Math.abs(a.get(i)-a.get(j)) <= 1){
counter++;
}
}
if(counter > max)
max = counter;
counter = 0;
}
return max+1;
}
While this one, gets a different output -
public static int pickingNumbers(List<Integer> a) {
// Write your code here
int max = 0;
int counter = 0;
Collections.sort(a);
for(int i = 0; i < a.size(); i++){
for(int j = i+1; j< a.size(); j++){
if(Math.abs(a.get(i)-a.get(j)) <= 1){
counter++;
}
}
if(counter > max){
max = counter;
counter = 0;
}
}
return max+1;
}
As you can see, the difference between the 2 codes are just the brackets after the if(counter > max) part. In the latter case, the counter is always 1 unit more than it should be.
Can anyone please explain it to me, why the code behaves different in this case?
It's because in the first snippet counter = 0; is not in the if block.
When if is not enclosed in brackets, it only evaluates the first instruction after it, so the counter = 0; is always executed.
Here's an example with better indentation:
public static int pickingNumbers(List<Integer> a)
{
int max = 0;
int counter = 0;
Collections.sort(a);
for(int i = 0; i < a.size(); i++)
{
for(int j = i+1; j< a.size(); j++)
{
if(Math.abs(a.get(i)-a.get(j)) <= 1)
{
counter++;
}
}
if(counter > max)
max = counter;
counter = 0; // Not in the if statement, so the counter is always reset!
}
return max+1;
}
const genObj = (ar) => {
let obj = {}
for(let i of ar) {
!(obj[i])? obj[i] = 1 : obj[i]++
}
return obj
}
function pickingNumbers(a) {
// Write your code here
let obj = genObj(a)
let k = Object.keys(genObj(a))
let i = 0
let max = 0
while (i <= k.length - 1) {
for(let j = i; j <= k.length - 1; j++){
if(i === j) continue
if(Math.abs(k[i] - k[j]) <= 1) {
if(obj[k[i]] + obj[k[j]] > max)
max = obj[k[i]] + obj[k[j]]
}
}
i++
}
return max > Math.max(...Object.values(obj)) ? max : Math.max(...Object.values(obj))
}
please tell me if another way to show nonEquivalence of loops
for(int i = 0; i < 10; i++){
if (i % 2 == 0)
continue;
System.out.println(i);
}
//non equivalent statement. is there any like this(without continue)
int i = 0;
while(i < 10){
if (i % 2 == 0)
continue;
System.out.println(i);
}
From what i gather from you code, you want to display only odd number in your loop. Try this
for(int i = 0; i < 10; i++){
if (i % 2 != 0)
System.out.println(i);
}
Instead of finding when i is even and doing the continue statement, simply "reverse" the condition. The same goes for the while
I am trying to make the following number line is Java
2,3,5,7,11,13,17 (Prime Numbers)
I tried this code
for(int i =0; i <= 100; i++) {
if(i < 2) {
continue;
}
for(int j = 2; j < 1; j++) {
if(i % j == 0) {
break;
} else {
System.out.print(i + ",");
}
}
}
But it doesn't work
Anyone help please?
Your code is quite poor, but the minimal amount of changes needed to make it work yields this code:
outerLoop:
for(int i = 0; i <= 100; i++) {
if(i < 2) {
continue;
}
for(int j = 2; j < i; j++) {
if(i % j == 0) {
continue outerLoop;
}
}
System.out.print(i + ",");
}
But a further improvement would be to start the first loop at 2 right away:
outerLoop:
for(int i = 2; i <= 100; i++) {
for(int j = 2; j < i; j++) {
// and so on...
EDITED
There are a lot of errors in that code, first of all that second loop is a infinite loop and second one that the System.out.println line should not be in second loop it should be at end of first loop! If you place it in second it will print numbers hundreds of time.
This is the correct code :
for(int i = 2; i <= 100; i++)//begin loop from 2 instead of 0
{
boolean flag = true;
for(int j = 2; j < i; j++)
{
if(i % j == 0)
{
flag = false;
break;
}
}
if(flag)System.out.print(i + ",");
}
You need to set a flag to check if a factor was found outside the loop.
I was asked the below question in an interview:
Given an array of integers, write a method to find indices m and n such that
if you sorted elements m through n, the entire array would be sorted. Minimize
n-m. i.e. find smallest sequence.
find my answer below and please do comment on the solution. Thanks!!!
At last I have got a solution to the problem, please feel free to comment.
Lets take an example:
int a[] = {1,3,4,6,10,6,16,12,13,15,16,19,20,22,25}
Now if i will put this in to the graph (X-coordinate -> array index and Y-coordinate -> array's value) then the graph will look like as below:
Now if we see the graph there are two places where dip happens one is after 10 and another after 16. Now in the zig zag portion if we see the min value is 6 and max val is 16. So the portion which we should sort to make the whole array sorted is between (6,16). Please refer to the below image:
Now we can easily divide the array in to three part. And middle part the one which we want to sort so that the whole array will be sorted. Please provide your valuable inputs. I tried to explain to my label best, please let me know if i want to explain more. Waiting for valuable inputs.
The below code implements the above logic:
public void getMN(int[] a)
{
int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE;
for(int i=1; i<a.length; i++)
{
if(a[i]<a[i-1])
{
if(a[i-1] > max)
{
max = a[i-1];
}
if(a[i] < min)
{
min = a[i];
}
}
}
if(max == Integer.MIN_VALUE){System.out.println("Array already sorted!!!");}
int m =-1, n =-1;
for(int i=0; i<a.length; i++)
{
if(a[i]<=min)
{
m++;
}
else
{
m++;
break;
}
}
for(int i=a.length-1; i>=0; i--)
{
if(a[i]>=max)
{
n++;
}
else
{
n++;
break;
}
}
System.out.println(m +" : "+(a.length-1-n));
System.out.println(min +" : "+max);
}
It's easier to find the max value starting from the end of array:
public void FindMinSequenceToSort(int[] arr)
{
if(arr == null || arr.length == 0) return;
int m = 0, min = findMinVal(arr);
int n = arr.length - 1, max = findMaxVal(arr);
while(arr[m] < min)
{
m ++;
}
while(arr[n] > max)
{
n --;
}
System.out.println(m);
System.out.println(n);
}
private int findMinVal(int[] arr)
{
int min = Integer.MAX_VALUE;
for(int i = 1; i < arr.length; i++)
{
if(arr[i] < arr[i-1] && arr[i] < min)
{
min = arr[i];
}
}
return min;
}
private int findMaxVal(int[] arr)
{
int max = Integer.MIN_VALUE;
for(int i = arr.length - 2; i >= 0; i--)
{
if(arr[i] >= arr[i+1] && arr[i] > max)
{
max = arr[i];
}
}
return max;
}
Actually, I came up with something like that:
public static void sortMthroughN(int[] a)
{
int m = -1;
int n = -1;
int k = -1;
int l = -1;
int biggest;
int smallest;
// Loop through to find the start of the unsorted array.
for(int i = 0; i < a.length-1; i++)
if(a[i] > a[i+1]) {
m = i;
break;
}
// Loop back through to find the end of the unsorted array.
for(int i = a.length-2; i > 0; i--)
if(a[i] > a[i+1]) {
n = i;
break;
}
biggest = smallest = a[m];
// Find the biggest and the smallest integers in the unsorted array.
for(int i = m+1; i < n+1; i++) {
if(a[i] < smallest)
smallest = a[i];
if(a[i] > biggest)
biggest = a[i];
}
// Now, let's find the right places of the biggest and smallest integers.
for(int i = n; i < a.length-1; i++)
if(a[i+1] >= biggest) {
k = i+1; //1
break;
}
for(int i = m; i > 0; i--)
if(a[i-1] <= smallest) {
l = i-1; //2
break;
}
// After finding the right places of the biggest and the smallest integers
// in the unsorted array, these indices is going to be the m and n.
System.out.println("Start indice: " + l);
System.out.println("End indice: " + k);
}
But, I see that results are not the same with your solution #Trying, did i misunderstand the question? By the way, at the and of your code, it prints
4 : 9
6 : 16
What are these? Which ones are indices?
Thanks.
EDIT: by adding place marked as 1 this:
if(a[i+1] == biggest) {
k = i;
break;
}
and 2:
if(a[i+1] == smallest) {
l = i;
break;
}
it is better.
Actually, you can have two pointers and the last pointer moves backward to check start index of the shortest unsorted sequence. It's kind of O(N2) but it is more cleaner.
public static int[] findMinUnsortedSequence(int[] array) {
int firstStartIndex = 0;
int startIndex = 0;
int endIndex = 0;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < i; j++) {
if (array[j] <= array[i]) {
startIndex = j + 1;
} else {
endIndex = i;
if (firstStartIndex == 0) {
firstStartIndex = startIndex;
}
}
}
}
return new int[]{firstStartIndex, endIndex};
}
public void removeDups() {
int i, k, j, lastFound = 0;
if (this.nElements < 1) {
System.out.println("Empty Array");
} else {
for (i = 0; i < this.nElements; i = lastFound) //outer loop
{
for (j = i + 1; j < this.nElements; j++) {
if (this.arr[i] == this.arr[j]) {
lastFound = i;
for (k = i; k < this.nElements; k++) {
this.arr[k] = this.arr[k + 1];
}
this.nElements--;
break;
}
}
}
for (i = 0; i < this.nElements; i++) {
System.out.println(this.arr[i]);
}
}
}
the previous method removes duplicates from the object invoking it (Array),the problem is that i want the outer loop to begin from a certain position every increment, i assign the value of that position to the variable lastFound and put that variable in the incremental part of the loop but the program goes to infinite loop and never stops, what is the problem with that?
You're setting i = lastFound at every iteration. At the start of the outer loop, initialize lastFound to i + 1. That way it will increment normally if you don't reset lastFound.
Alternatively, get rid of lastFound and when you find a match, set i = i - 1, start the k loop at i + 1 instead of i, and change the increment expression in the outer loop from i = lastFound to i++. I would also simplify your code by using System.arraycopy:
public void removeDups() {
if (nElements < 1) {
System.out.println("Empty Array");
} else {
for (int i = 0; i < nElements; i++) {
for (int j = i + 1; j < nElements; j++) {
if (arr[i] == arr[j]) {
System.arraycopy(arr, i + 1, arr, i, nElements - (i + 1));
nElements--;
i--;
break;
}
}
}
for (i = 0; i < nElements; i++) {
System.out.println(arr[i]);
}
}
}
Think of this: In first iteration,
i = 0
now if this is false: this.arr[i] == this.arr[j] then lastfound is never changed(remains 0), which will lead into infinite loop.
To fix the problem, handle the no match scenario.