How to check that all values are equal in array using recursion? - java

I am trying to solve this algorithm recursively; I want to check that all values in the array are the same (or equal to each other). If all values are equal, return true, if they are not, return false. My code is not passing any tests.
public boolean allEqual(int[] a, int start, int end){
if (start > end) return false;
if (a.length==0) return false;
if (start==end && a[start] == a[end]) return true;
if (a[start] != a[end]){
return false;
}
return allEqual(a, start++, end);
}

change
return allEqual(a, start++, end);
to
return allEqual(a, start+1, end);
start++ passes the original value of start to the recursive call (that's what post increment operator returns), so your recursion will never end and you are probably getting a StackOverflowError.

It may be the easiest to simply take the first value of the array and go through until a single value is not the same.
public void allEqual(int[] arr) {
if(arr.length==0) return false;
for(int i=0; i<arr.length; i++)
if(arr[0]!=arr[i]) return false;
return true;
}
Edit: Realized this answer is for doing it with recursion and my answer doesn't do that.

You can solve it using the classic divide and conquer method. Divide the array into halves until there are two elements, and then check if those are equal. Then conquer them and compare the values. Something like this:
class Ideone {
static boolean checkEquals(int a[], int start, int length) {
if (length==2)
return a[start]==a[start+1] && a[start]==a[0];
else
return checkEquals(a,start+0,length/2) &&
checkEquals(a,start+length/2,length/2);
}
public static void main (String[] args) {
int a[]={1,1,1,1,1,1,1,1};
System.out.println(checkEquals(a,0,8));
}
}
Executed here.

Related

Binary Search: why it won't stop when I return the result

I can't understand why the function will not stop and return the mid, but it keeps going down to the return -1.
public class BinarySearch {
public static int BS(int[] arr, int target, int first, int last) {
if(first != last) {
int mid = first + (last - first)/2;
System.out.println("arr[mid] = "+arr[mid]);
if(arr[mid] != target) {
if(target < arr[mid]) {
last = mid - 1;
System.out.println("last is "+last);
BS(arr, target, first, last);
}else {
first = mid + 1;
BS(arr, target, first, last);
}
}else {
System.out.println("Found!");
return mid;
}
System.out.println("test");
}
if(arr[first] == target) return first;
System.out.println("Not found!");
return -1;
}
public static void main(String[] args) {
int[] test = {0,1,2,4,6,7,9,10};
int result = BS(test, 7, 0, test.length-1);
System.out.println(result);
}
}
When you have return mid 3 calls deep it is 2nd BS that gets that value and since it does not use the value it is lost. Instead it continues to the 3 last lines of the function since that is what the code tells it to do. Unless the element to be found is the first element you never return it.
Recursive functions are not treated special. Their argument, local variables and state are different is not shared and a return only returns that one call and does not affect the other ongoing calls.
You could replace each recursive call with a similar function BS1 that calls BS2 etc. that produces the same code at each level and it will work the same. Then there will be no recursive call, but it will work the same way. A return in BS4 will not affect BS3 except for its returned value it should use. One return in BS3 does not cancel the calls BS2, BS1 as they are waiting for an answer to continue their flow. With a return BS2(arr, target, first, last); that continued flow is to return the value that the call to BS2 returns.
Your first calls that returns is System.out.println. If it worked that the first return was the final result then its value would be the result of your logic.

why can't i change base address of array in java while passing it as parameter?

I have written some code to find the first index of an element in an array in java but it's not working because arr+1 is not working. Can someone explain why I can't change the base address of the array in java?
public static int firstIndex(int[] arr, int n , int key ){
if(n==0){
return -1;
}
if(arr[0] == key)
{
return 0;
}
else{
int fi = firstIndex(**arr+1**,n-1,key);
if(fi==-1){
return -1;
}
else return fi+1;
}
Java arrays are not C arrays.
In C an array is (effectively, basically, but not quite exactly) a pointer to the element type and it's up to the code itself to communicate and implements the constraints (such as element type, array size, ...).
In Java an array is a first-class citizen: it has a specific type and knows what its own length is.
This also means that C-style "tricks" like just pointing to the second element of an array and treating that thing as an array itself won't work.
For your specific case you can simply pass the start-index in addition to the array like this:
public static int firstIndex(int[] arr, int start, int n, int key) {
if(n==0) {
return -1;
}
if (arr[start] == key) {
return 0;
} else {
int fi = firstIndex(arr, start+1, n-1, key);
if (fi == -1) {
return -1;
} else {
return fi+1;
}
}
}

Partition Equal Subset Sum Top Down TLE

I am Solving Partition Equal Subset Sum of leetcode.
Problem States:
Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.
Note:
Each of the array element will not exceed 100.
The array size will not exceed 200.
I Wrote the Code for the following as
class Solution {
public boolean canPartition(int[] nums) {
int sum=0;
for(int i=0;i<nums.length;i++)
{
sum=sum+nums[i];
}
if(sum%2!=0)
{
return false;
}
int target=sum/2;
return helper(nums,target,nums.length);
}
boolean helper(int nums[],int sum,int n)
{
if(sum==0)
{
return true;
}
if(sum<0)
{
return false;
}
if(n==0)
{
return false;
}
return helper(nums,sum-nums[n-1],n-1)||helper(nums,sum,n-1);
}
}
Notice that I did not included the condition
if(sum<nums[n-1])
{
return false;
}
in the base case as i have included
if(sum<0)
{
return false;
}
which is the same thing as it would just add 1 more recursive call and then return false.
This code works for 89 of the test cases but gives TLE error for
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,100]
Now if the modify the same code and include
if(sum<nums[n-1])
{
return false;
}
and remove
if(sum<0)
{
return false;
}
i.e
class Solution {
public boolean canPartition(int[] nums) {
int sum=0;
for(int i=0;i<nums.length;i++)
{
sum=sum+nums[i];
}
if(sum%2!=0)
{
return false;
}
int target=sum/2;
return helper(nums,target,nums.length);
}
boolean helper(int nums[],int sum,int n)
{
if(sum==0)
{
return true;
}
if(n==0)
{
return false;
}
if(nums[n-1]>sum)
{
return false;
}
return helper(nums,sum-nums[n-1],n-1)||helper(nums,sum,n-1);
}
}
The code works fine and passes all the Test Cases.
Since both the code are same how is that one extra recursive call giving me TLE?
Is there is something else ?
The test cases are really weak. First one should get TLE as you did not use dynamic programming but performed a plain backtrack. Second one should get WA. If you used memoization your complexity would be O( totalSum * arraySize) but the complexity of your code is O(2 ^ arraySize).
now observe you have two options in every state. Either you pick the element or not. Even if this condition is true if(nums[n-1]>sum) , the second option is valid - going forward not picking the item. But your second code ignores both the cases for that condition reducing the calls to the point your solution takes less than 1 millisecond which is faster than most correct solution. As there was no counter test cases for the second solution it passed.

Looping through two arrays to check if equal

Trying to check if two arrays are equal, meaning same length and same elements in positions.
I've tried Arrays.equals(1,2) but it's still coming out as false, while it needs to be coming out as true.
I've tried to create a nested for loop to check each index but I am still getting false.
My code:
public boolean equals(double[] s) //for loop checking each element
{
if (s==null)
{
return false;
}
for (int i=0;i<data.length;i++)
{
for(int j=0;j<s.length;j++)
{
if (data[i]!=s[j])
{
return false;
}
}
}
return true;
}
Don't reinvent the wheel!
public boolean equals(double[] s) {
return Arrays.equals(s, data);
}
Arrays.equals() compares array lengths and each element.
if you want to see if they have the same elements but you don't care if they have the same order, sort them first.
Arrays.sort(data);
Arrays.sort(s);
return Arrays.equals(data,s);
You don't need a nested loop to check the elements. In fact, your code is wrong in a sense that it's checking all the elements from one array to another.
You might want to
// Check to make sure arrays have same length
if (data.length != s.length)
return false;
for (int i=0;i<data.length;i++)
{
if (data[i]!=s[i])
{
return false;
}
}
return true;
You can use as below :
if(arr1.length!=arr2.length)
return false;
for(int index=0;index<arr1.length;index++)
{
if (arr1[index]!=arr2[index])
return false;
}
return true;

checking whether two sequences have the same values in the same order (beginning java)

I want to add a method to a class I made that checks whether the two sequences have the same values in the same order.
Here is what I have so far:
public class Sequence {
private int[] values;
public Sequence(int size) { values = new int[size]; }
public void set(int i, int n) { values[i] = n; }
}
public boolean equals (Sequence other)
...??
The first part of the class I think is correct but I'm having a lot of trouble with the method that tests if the values are in the same order. Ideas and feedback would be much appreciated :)
If you want to say wether 2 Sequences are equals, you can override equals method and hashCode to follow contract.
Example using Eclipse tool:
public class Sequence {
private int[] values;
public Sequence(int size) { values = new int[size]; }
public void set(int i, int n) { values[i] = n; }
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode(values);
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Sequence other = (Sequence) obj;
if (!Arrays.equals(values, other.values))
return false;
return true;
}
}
Then in a main class you can do the following thing
public static void main(String args[]){
Sequence s = new Sequence(5);
Sequence s2 = new Sequence(5);// new Sequence(4)
s.set(0, 1);
s2.set(0, 1);
System.out.println(s.equals(s2));//will print true
}
You have to take care that if you use my comment code (new Sequence(4)) this will return false and perhaps is not what you want! Then you will have to implement your own equals and not autogenerated by ide.
Arrays have a built in .equals() method: .equals(int[], int[])
Very simple, but hope this helps.
public boolean equals (Sequence other) {
// if sizez are different, automatic false
if (this.getValues().length != other.getValues().length)
return false;
else
int[] array1 = other.getValues();
int[] array2 = this.getValues();
// if any indices are not equal, return false
for (int i = 0; i < other.getValues().length; i++){
if (array1[i] != array2[i])
return false;
}
// it not returned false, return true
return true;
}
First and foremost, you will need to make your .equals() method a member of your Sequence class. Otherwise, you will only have access to one Sequence object.
If you want to check if 2 arrays have the same elements in the same order, all you need to do is compare each element in turn. Is the first element of this one the same as the first element of the other, etc. When you come across a pair of elements that are different, you will be able to return false. Otherwise, you can return true when you have checked each pair of elements.
One issue you may encounter is arrays of different size. Depending on what you're trying to do, you may want to either return false immediately without checking the elements or stop when you reach the end of the shorter array. Based off your question, you probably want the former, but that depends on what problem you are trying to solve.
Your .equals() method will be able to access the values arrays of both this and other even if they aren't public. This is because .equals() as a function of the Sequence class is allowed to access all the members of Sequence, even in Sequence objects other than this.
With this information, you should be able to write your .equals() method.
public boolean equals (Sequence other){
int[] first = this.getValues();
int[] second = other.getValues();
boolean same = true;
if(first.length != second.length){
return false;
}
for(int i = 0; i < first.length; i++){
if(first[i] != second[i]){
return false;
}
}
return same;
}
Note: you will have to make the values array public in the Sequence class or add a getter method to the Sequence class...a getter would be the better option

Categories

Resources