Confused on how to evaluate the while !result in the while function - java

I'm not sure how to evaluate this line to understand what my code does
while (i < data.length && !result) {
this is my full code.
public static boolean {2,6,-3,7,3} (int[] data, int val) {
boolean result = false;
int i = 0;
while (i < data.length && !result) {
if (data[i] == val) {
result = true;
}
i++;
}
return result;
}

The result variable is used as a way to break out of the while loop before i reaches data.length. It causes the loop to be exited when result becomes true.
It is equivalent to:
boolean result = false;
int i = 0;
while (i < data.length) {
if (data[i] == val) {
result = true;
break; // here we break from the loop explicitly when result becomes true
}
i++;
}
return result;
or even simpler:
int i = 0;
while (i < data.length) {
if (data[i] == val) {
return true; // here we break from the loop using a return statement
// when a match is found
}
i++;
}
return false;

boolean result = false; //initial declaration
int i = 0;
while (i < data.length && !result) {
if (data[i] == val) {
result = true;
// the !result evaluates to false once you've reached this statement
}
So as soon as you find a match of val in the data[]. The flow breaks out of the loop since the condition becomes
any() && false => false
where any() could be either true or false based on your first condition i < data.length.

Related

Leetcode 9. Palindrome Number

I am trying to do this converting the integer to a string.
Inside the if clause, if I used s.charAt(i) == s.charAt(j) first then i++, j--, I couldn't pass the test of input = 121, I got false instead of true. But if I put s.charAt(i) != s.charAt(j) first, then accepted.
Wrong answer:
class Solution {
public boolean isPalindrome(int x) {
String s = String.valueOf(x); //n
int l = s.length();
int i = 0;
int j = l - 1;
while (i <= j) {
if (s.charAt(i) == s.charAt(j)) {
i++;
j--;
}
return false;
}
return true;
}
Accepted answer:
class Solution {
public boolean isPalindrome(int x) {
String s = String.valueOf(x); //n
int l = s.length();
int i = 0;
int j = l - 1;
while (i <= j) {
if (s.charAt(i) != s.charAt(j)) {
return false;
}
i++;
j--;
}
return true;
}
}
What did I miss?
The wrong solution returns false in any case and the correct solution only returns false when s.charAt(i) != s.charAt(j) is true.
If you want to skip return false; in the first code, you either need to move it into an else clause or use continue; in the if clause in order to directly jump to the next loop iteration.

How to properly check if two jagged arrays are the same size?

I am having trouble checking if two jagged java arrays are the same size. My function isn't returning the correct result. The hw problem I'm working on states that the function should return true if both arrays are null or are the same size, and should return false if the only one of the array's is null or if they have a different size.
I have tried executing the code to see what boolean value is returned, however the console outputs nothing.
static boolean arraySameSize(int[][] one, int[][] two) {
boolean value = false;
if (one == null && two == null) {
value = true;
} else if ((one == null && two != null) || (two == null && one != null)) {
value = false;
} else {
int count = 0;
int count2 = 0;
for (int i = 0; i < one.length; i++) {
for (int j = 0; j < one[i].length; j++) {
count++;
}
}
for (int i = 0; i < two.length; i++) {
for (int j = 0; j < two[i].length; j++) {
count2++;
}
}
if (count == count2) {
value = true;
} else {
value = false;
}
}
return value;
}
I expect the output to be true if both array's are null or are the same size, false otherwise. I am getting an error from the auto-grader stating the following:
java.lang.AssertionError: Incorrect result: expected [false] but found [true]
What should I adjust to ensure that value has the correct value when it's returned?
try this.
static boolean arraySameSize(int[][] one, int[][] two) {
if (one == null && two == null) return true;
if (one == null || two == null) return false;
if (one.length != two.length) return false;
for (int i = 0, size = one.length; i < size; ++i) {
int[] oneRow = one[i];
int[] twoRow = two[i];
if (oneRow == null && twoRow == null) continue;
if (oneRow == null || twoRow == null) return false;
if (oneRow.length != twoRow.length) return false;
}
return true;
}

Q: Solve almostIncreasingSequence in Java (Codefights)

I can't pass the final hidden test.Could you tell me what I miss?Thanks in advance.
Here are the statements: Given a sequence of integers as an array, determine whether it is possible to obtain a strictly increasing sequence by removing no more than one element from the array.
boolean almostIncreasingSequence(int[] sequence)
{
boolean increase = true;
List<Integer> list = new ArrayList<>();
for (int a :sequence )
{
list.add(a);
}
System.out.println(list);
if(list.size()==1)
{
return false;
}
for (int i = 0;i < list.size()-1 ;i++ )
{
if (list.get(1)<=list.get(0))
{
list.remove(0);
break;
}
if(list.get(i+1)<=list.get(i))
{
if (list.get(i+1)>list.get(i-1))
{
list.remove(i);
}
else
{
list.remove(i+1);
}
break;
}
}
for (int i =0;i<list.size()-1 ;i++ )
{
if (list.get(i+1)<list.get(i) || list.get(i+1)==list.get(i) )
{
increase = false;
}
}
return increase;
}
This is the linear solution I came up with. It involves muting the array so you don't have to loop through the array again.
boolean almostIncreasingSequence(int[] sequence) {
int removed = 0;
for (int i = 0; i < sequence.length - 2 && removed <= 2; i ++) {
int a = sequence[i];
int b = sequence[i+1];
int c = sequence[i+2];
if (a >= b) {
removed++;
sequence[i] = b -1;
}
if (b >= c){
removed++;
if (a == c) {
sequence[i+2] = b +1;
} else {
sequence[i+1] = a;
}
}
}
return removed <= 1;
}
Here's my solution with O(n) complexity
`
boolean almostIncreasingSequence(int[] sequence) {
int flag = 0;
int i = 0;
while(i<sequence.length-1){
if(sequence[i] < sequence[i+1]){
i = i+1;
continue;
} else {
flag = flag + 1;
if(i>0 && i+2 < sequence.length && sequence[i+1] <= sequence[i-1] && sequence[i+2] <= sequence[i]){
flag = flag + 1;
} else {
i = i+1;
}
if(flag > 1){
return false;
}
}
}
return true;
}
`
This worked for me
boolean almostIncreasingSequence(int[] sequence) {
int failed = 0;
boolean one_chance;
for(int i = 0; i < sequence.length - 1; i++){
int curr=i,next=i+1;
if(sequence[curr] >= sequence[next]) {
failed++;
if( curr > 0 && next < sequence.length - 1 ){
// Problem is not on head neither tail
// So check if removing one of 2 problematic numbers solves the issue
one_chance = false;
if( sequence[curr - 1] < sequence[next] )
one_chance = true ;
if ( sequence[curr] < sequence[next+1] )
one_chance = true ;
if( one_chance == false ) return false;
}
}
if( failed > 1 ) return false;
}
return true;
}
Spoiler Alert!
I could not pass the last hidden test either. So I spent 10,000 of my 12,300 coins (ouch!) to unlock them.
It turns out, the last test (#34) is expecting an outcome of true, and is passing an array of ints 100,000 long, in order from 1 to 100000! (So big that the only way I could see this was to do this in my code:
System.out.printf("length: %d%nlastValue:%d%n",
sequence.length, sequence[sequence.length - 1]);
I'm not sure why my code didn't pass, but I did at least unlock that hidden test, so now you can know what it is without having to spend coins to unlock it yourself.
I then got lazy and added this line at the top of my method to make it pass:
if (sequence.length == 100000
&& sequence[sequence.length - 1] == 100000) {
return true;
}
Here is a solution that works by using recursion to check the remainder of the array.
The issue is when the code hits a number that doesn't belong it can't be sure which of the two numbers is the offender so I just check the array starting from where the problem was detected and skipping the "bad" numbers. If it fails again while skipping a number it's game over.
This is in JavaScript, but it can easily be translated.
function almostIncreasingSequence(sequence) {
if(!sequence || sequence.length < 3) return true;
return checkSorted(sequence);
}
function checkSorted(arr, start = 0, skip) {
let last = arr[start === skip ? skip + 1 : start];
for(let i = start + 1; i < arr.length; i++) {
if(skip === i) continue;
let current = arr[i];
let lastIndex = skip === i - 1 ? i - 2 : i - 1;
let last = arr[lastIndex];
if(current <= last) {
if(skip !== undefined) return false;
return checkSorted(arr, i - 1, i) || checkSorted(arr, i - 1, i - 1);
}
}
return true;
}
def almostIncreasingSequence(sequence):
initial_length = len(sequence)-1
length = len(sequence)-1
count = 0
i = 0
while i < length:
if sequence[i] >= sequence[i+1]:
if i == 0:
sequence.pop(0)
count +=1
length = len(sequence)-1
i =0
elif sequence[i] == sequence[i+1]:
sequence.pop(i+1)
length = len(sequence)-1
i -= 1
count += 1
elif sequence[i] > sequence[i+1]:
if count ==0 and i + 1 == length:
return True
else:
if max(sequence) == sequence[i] and count == 0:
sequence.pop(i)
length = len(sequence)-1
i -= 1
count += 1
else:
sequence.pop(i+1)
length = len(sequence)-1
i -= 1
count +=1
else:
i += 1
length = len(sequence)-1
if count == 1:
if initial_length - length == 1:
return True
else:
return False
elif count > 1:
if initial_length - length > 1:
return False
else:
return True
boolean almostIncreasingSequence(int[] sequence) {
int count = 0;
int size = sequence.length;
if(size==1)
return true;
for(int i=0;i<size-1 && count<=1;i++){
if(sequence[i]>=sequence[i+1]) {
count++;
if(i>0 && (i+2)<size && sequence[i-1]>=sequence[i+1] && sequence[i]>=sequence[i+2]) {
count++;
}
}
}
return (count<=1);
}
boolean solution(int[] sequence) {
boolean increasing = true;
boolean isany = false;
for(int i=0;i<sequence.length;i++){
ArrayList<Integer> sequenceArrayList = new ArrayList();
for(int a : sequence){
sequenceArrayList.add(a);
}
sequenceArrayList.remove(i);
for(int j=0;j<sequence.length-2;j++){
if(sequenceArrayList.get(j)>=sequenceArrayList.get(j+1)){
increasing = false;
break;
}else{
increasing = true;
}
}
if(increasing){
isany = true;
}
}
return isany;
}

Counting number of unique adjacent pairs of same elements in an array

My function does not return the correct answer. My task is to count the two numbers in an array that are the same and next to each other here is a sample:
array_1 = {1,2,2,3,4,4,2}; ans = 2
array_2 = {2,2,3,4,4}; ans = 2
array_3 = {1,1,1,1,1,1,1}; ans = 1
array_4 = {1,2,3,4,2}; ans = 0
Here is my function. Observed output is given as comments.
public class countClampsTest
{
public static void main(String[] args)
{
int array_1[] = {1,2,2,3,4,4,2}; // expected result: 2
int array_2[] = {2,2,3,4,4}; // expected result: 2
int array_3[] = {1,1,1,1,1,1,1}; // expected result: 1
int array_4[] = {1,2,3,4,2}; // expected result: 0
System.out.println(countClamps(array_1)); // Returns 2
System.out.println(countClamps(array_2)); // Returns 1
System.out.println(countClamps(array_3)); // Returns 1
System.out.println(countClamps(array_4)); // Returns 0
}
static int countClamps(int[] arr) {
int result = 0;
int nextNext = 0;
for (int current = 0; current < arr.length - 1; current++) {
for (int next = current; next <= current + 1; next++) {
nextNext = next + 1;
if(nextNext >= arr.length) {
nextNext = arr.length -1;
}
if (arr[current] == arr[next] && current != next) {
if(arr[next] != arr[nextNext]) {
result++;
} else if(arr[next] == arr[nextNext] && arr.length % 2 == 0) {
result = 1;
}
}
}
}
return result;
}
}
I see a few issues in your code.
In the test:
if (arr[current] == arr[next] && current != next) {
you compare current with next; you could obtain the same result by starting the next loop at current+1 instead of current:
for (int next = current+1; next <= current + 1; next++) {
nextNext = next + 1;
...
if (arr[current] == arr[next]) {
...
}
}
which makes the loop redundant: it's only executed once, so the code above is equivalent to:
int next = current+1;
nextNext = next + 1;
...
if (arr[current] == arr[next]) {
...
}
Now in your inner test:
if(arr[next] != arr[nextNext]) {
result++;
} else if(arr[next] == arr[nextNext] && arr.length % 2 == 0) {
result = 1;
}
You can see that the first part of the second condition is always true, so it's equivalent to:
if(arr[next] != arr[nextNext]) {
result++;
} else if(arr.length % 2 == 0) {
result = 1;
}
The remaining condition means that you reset result to 1 if the array has an even number of elements (why?).
at the end of the array, result will not be incremented if the last two elements are equal, which is why you don't get the correct result in the second case.
Here is my solution:
static int countClamps(int[] arr) {
int result = 0;
for (int i = 1; i < arr.length; ++i) {
if (arr[i] == arr[i-1]
&& (i == arr.length-1 || arr[i] != arr[i+1])) {
++result;
}
}
return result;
}
A possible solution is: Stop you loop still one iteration earlier: use current < arr.length - 2 (this will cause nextNext to be within the array always). After your outer loop, just compare the last two elements of the array. If they are equal, add 1 to result. Done.
Except if the array has length 0 or 1, you will need to treat that specially.
I've added an extra boolean to keep track of already counted duplicates after each other.
static int countClamps(int[] arr) {
int result = 0;
int prev = 0;
boolean same = false;
for(int i = 0; i < arr.length; i++) {
if (i == 0) {
prev = arr[i];
} else {
if (arr[i] == prev) {
if (!same) {
result++;
same = true;
}
} else {
prev = arr[i];
same = false;
}
}
}
return result;
}
Once you've found a pair skip an index in loop.
public static int pairs(int[] list){
int pairs = 0;
for(int x = 1; x < list.length; x++){
if(list[x] == list[x-1]){
pairs++;
x=x+1;}
}
return pairs;
}

Solution of twoTwo riddle on codingBat in Java

The question is about Solving this problem from codingBat in Java.
Problem Statement:
Given an array of ints, return true if every 2 that appears in the array is next to another 2.
twoTwo({4, 2, 2, 3}) → true
twoTwo({2, 2, 4}) → true
twoTwo({2, 2, 4, 2}) → false
First of all going by the problem statement that every 2 that appears in the array is next to another 2. then
do you think as suggested the outcome for the first inputs shown above
should be true?
twoTwo({4, 2, 2, 3}) → true
Because as I see it it the first 2 itself that appears in the array is next to 4 not 2
am I confused or it's a wrongly stated question? I had to grapple with the problem to somehow get the right code to crack the problem as below but it seems a hotch potch:
public boolean twoTwo(int[] nums) {
if(nums.length==0)
{
return true;
}
if(nums.length==1)
{
return !(nums[0]==2);
}
if((nums.length==2))
{
if((nums[1]==2)&&(nums[0]==2))
return true;
else
return false;
}
for(int i=0;i+2<nums.length;i++)
{
if((nums[i]!=2)&&(nums[i+1]==2)&&(nums[i+2]!=2))
return false;
}
if((nums[nums.length-2]!=2)&&(nums[nums.length-1]==2))
return false;
return true;
}
Any efficient alternate solutions are welcome.
Thanks!
Here's how I would do it. It's a bit easier to follow I think:
public boolean twoTwo(int[] nums)
{
for (int i=0; i<nums.length; i++)
{
if (nums[i] != 2)
continue;
if (i >= 1 && nums[i-1] == 2)
continue;
if (i < (nums.length-1) && nums[i+1] == 2)
continue;
return false;
}
return true;
}
The solution I got to the problem is below:
public boolean twoTwo(int[] nums) {
final int length = nums.length;
for (int i = 0; i < length;){
int count = 0; // Used to count following 2's
while(i < length && nums[i++] == 2){
count++;
}
if(count == 1){ // No adjacent 2's! Set doesn't work.
return false;
}
}
return true; // Didn't come across a lone 2
}
The way that I handle this, is that I count all the adjacent 2's. If the count is not 1, we are good. This means that there was either no 2 at that index, or a group of 2's was present. This holds, since we traverse the array in a single direction.
A good thing about this solution is that it will work for an array of any size. Note that it would have a linear complexity, even though 2 loops are present. They both just traverse using the same index value, only ever sweeping over the array once.
If at any time we find a 2, then check the following only to find there are 0 following 2's (denoted by count), we return false.
public boolean twoTwo(int[] nums) {
for (int i=0; i<nums.length; i++) {
if(nums[i] == 2) { //If current number is 2
if (
// if prev or next is not 2 return true
!(i-1>=0 && nums[i-1] == 2) &&
!(i+1<nums.length && nums[i+1] == 2)
) { return false; }
}
}
return true;
}
For the sake of simplicity and clean code, this code forces the check
i-1>=0 and i+1<nums.length in every iteration.
This can be avoided by iterating from (1...nums.length-1) and checking the edge cases separately.
I know this is an old question, but I came up with a new solution. Short, and with no complicated conditionals.
public boolean twoTwo(int[] nums) {
int position = -2;
boolean result = true;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 2) {
result = position == i - 1;
position = i;
}
}
return result;
}
Next to means either before or after. Loop through each number and check the values before and after to see if there's an adjacent 2. The special cases are when you're checking the 1st and last element because there won't be an element before or after to check.
public boolean twoTwo(int[] nums) {
if(nums.length == 1 && nums[0] == 2)
return false;
for(int i = 0; i < nums.length; i++) {
if(nums[i] == 2) {
if(i == 0) { // check the next element
if(nums[i+1] != 2)
return false;
}
else if(i == (nums.length - 1)) { // check the previous element
if(nums[i-1] != 2)
return false;
}
else { // check both
if(nums[i+1] != 2 && nums[i-1] != 2)
return false;
}
}
}
return true;
}
Here is mine solution to two two's problem. I think my solution is clear i.e. understandable.
package codingbat.array2;
public class TwoTwo
{
public static void main(String[] args)
{
}
public boolean twoTwo(int[] nums)
{
boolean twoTwo = true;
for (int i = 0; i < nums.length; i++)
{
if (2 == nums[i])
{
if (i > 0 && 2 == nums[i - 1]
|| nums.length > i+1 && 2 == nums[i+1])
{
twoTwo = true;
i++;
}
else
{
twoTwo = false;
break;
}
}
}
return twoTwo;
}
}
public boolean twoTwo(int[] nums) {
for(int i = 0 ; i < nums.length; i++ ) {
int count = 0;
if(nums[i] == 2 ) {
while(i+1 < nums.length && nums[i+1] == 2 ) {
count ++;
i++;
}
if (count == 0 ) {
return false;
}
}
}
return true;
}
public boolean twoTwo(int[] nums) {
for(int i = 0;i<nums.length;i++)
if(nums[i]==2 && !isTwoBeforeOrAfter(nums,i))
return false;
return true;
}
private boolean isTwoBeforeOrAfter(int[] nums,int i){
return i+1<nums.length && nums[i+1]==2 || i-1>=0 && nums[i-1]==2;
}
public boolean twoTwo(int[] nums) {
float two = 0;
double count = 0;
for (int i = 0; i < nums.length; i++) {
if (i < nums.length - 2 && nums[i] == 2 && nums[i + 1] == 2 && nums[i + 2] == 2) {
return true;
}
if (i < nums.length - 1 && nums[i] == 2 && nums[i + 1] == 2) {
count++; //count the pair
}
if (nums[i] == 2) {
two++;
}
}
return ((count * 2) == two);
//each pair contain 2 ,two"s .so pair*2=total two counts
//count
}
public boolean twoTwo(int[] nums) {
boolean two = false;
boolean result = true;
for (int i=0; i<nums.length; i++) {
if (nums[i] == 2) {
if (two) {
result = true;
} else {
result = false;
}
two = true;
} else {
two = false;
}
}
return result;
}
Here's my solution. Enjoy.
public boolean twoTwo(int[] nums)
{
//If the length is 2 or more
if (nums.length >= 2)
{
//If the last char is a 2, but the one before it is not a char, we return false;
if (nums[nums.length - 1] == 2 && nums[nums.length - 2] != 2)
{
return false;
}
//If larger than three, we create a for loop to test if we have any 2s that are alone.
if (nums.length >= 3)
{
for (int i = 1; i < nums.length-1; i++)
{
//If we find a two that is alone, we return false;
if ((nums[i] == 2) && (nums[i-1] != 2 && nums[i+1] != 2))
{
return false;
}
}
}
//If we don't return false, we return true;
return true;
}
//If we have less than two characters, we return true if the length is 0, or \
//One the one number there is not a 2.
else
{
return ((nums.length == 0) || !(nums[0] == 2));
}
}
public boolean twoTwo(int[] nums) {
int len = nums.length;
Boolean check = false;
int count = 0;
for(int i=0; i<len ; i++){
if(nums[i]==2){
count++;
if((i<len-1 && nums[i+1]==2) || (i>0 && nums[i-1]==2)) check = true;
else check = false;
}
}
if(count==0) check = true;
return check;
}
public boolean twoTwo(int[] nums) {
int count = 0;
for (int i = 0; i < nums.length; i++)
if (nums[i] == 2) count++;
else if (count == 1) return false;
else count = 0;
return count != 1;
}
Every time we encounter a 2, we increase the counter of consecutive 2s.
When it's not a 2 — but the counter indicates that there was a single 2 before it —, we know we've found a lonely 2.
Otherwise the search continues, resetting the 2-counter.
easy to understand)
static boolean twoTwo(int[] nums) {
int len = nums.length;
boolean result = true;
boolean found = false;
for(int i=0; i<len; i++){
//if it not 2, no meaning to go true other if-s
if(nums[i] !=2) {found = false; continue;}
// if current element is 2 and found is true(last element is 2)
if(nums[i] ==2 && found) result = true;
// if current element is 2, but last element not
if(nums[i] ==2 && !found){
found = true;
result = false;
}
}
return result;
}
This might be easier to follow if the other suggestions confuse you..
public boolean twoTwo(int[] nums) {
int len = nums.length;
if(len == 0) return true; // no 2's to worry about
if(len == 1) return nums[0] != 2; // make sure it's not a single 2
for(int i = 1; i < len -1; i++){ // loop for each except edge cases
if(nums[i] == 2 && nums[i-1] != 2 && nums[i+1] != 2) return false; // check surrounding
}
if(nums[len - 1] == 2) return nums[len - 2] == 2; //if last num is 2 check for 2 before it
return true; // made it here it's true
}
that one was tough for me... here's mine:
public boolean twoTwo(int[] nums) {
boolean two = false, res = true;
for (int i : nums) {
if (i == 2) {
if (two)
res = true;
else {
two = true;
res = false;
}
} else {
two = false;
}
}
return res;
}
One more alternative. Here is the main idea:
Convert array into String. Add a character different from "2" at the beginning and end of the string, to avoid going out of bounds.
Look for standalone "2" - if element of the string is equal to 2, check whether chars immediately before and after are also equal to "2". If they are it means that not all "2" are adjacent, and therefore method returns false.
public boolean twoTwo(int[] nums) {
// convert array to string
String text = "";
for (int i = 0; i < nums.length; i++) {
text += String.valueOf(nums[i]);
}
text = " " + text + " ";
// find standalone "2"
for (int i = 1; i < text.length() - 1; i++) {
if (text.charAt(i) == '2' && text.charAt(i - 1) != '2' && text.charAt(i + 1)
!= '2') {
return false;
}
}
return true;
}

Categories

Resources