Partition Equal Subset Sum Top Down TLE - java

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.

Related

How to use a "Do While" loop to iterate through a list

public static boolean hasGreaterDoWhile(List<Integer> numbers, int number) {
int d = 0;
do {
if (numbers.get(d) > number){
return true;
}
d++;
}
while (d < numbers.size());
return false;
}
(JAVA only)
P.s This is a function i have tried, in order to check the first argument, and if it contains a number that is larger than the second argument, it will then return true, and flase otherwise.
Note that it is using do while loop. I just don't know which part of this code i have done wrong, because the system keeps telling me that "java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0".
Thank u, any hint will be much appriciated.
your list of Integers is empty. you can't access an index of an empty list:
public static boolean hasGreaterDoWhile(List<Integer> numbers, int number) {
int d = 0;
if (numbers.isEmpty()) return false;
do {
if (numbers.get(d) > number){
return true;
}
d++;
}
while (d < numbers.size());
return false;
}
A do-while control block works as follows:
Execute the do block
Check the condition. If it holds, return to (1)
Notice the order of this flow. Unlike a standard while, do-while will always execute one iteration before checking the condition. Therefore, for an empty list you will always try to access the 0-index element of the table, which does not exist, hence the error. You can use a while loop to avoid this:
public static boolean hasGreaterDoWhile(List<Integer> numbers, int number) {
int d = 0;
while (d < numbers.size()) {
if (numbers.get(d) > number){
return true;
}
d++;
}
return false;
}
You should check whether the collection is empty
like this
if(numbers == null || numbers.isEmpty()) {
return false;
}
int d = 0;
do {
if (numbers.get(d) > number){
return true;
}
d++;
}
while (d < numbers.size());
return false;

Given an array of numbers, the task is to print only those numbers which have only 1, 2 and 3 as their digits

Im currently working on a program to given integer input from user, print only those ones contain numbers 1 2 or 3. Here is my code so far:
public static void main(String[] args){
Scanner s = new Scanner(System.in);
int[] x=new int[5];
System.out.println("Enter 5 integers: ");
for(int i=0; i<x.length;i++) {
x[i]=s.nextInt();
boolean temp=recursion(x[i]);
if(temp==true) {
System.out.print(x[i]);
}
}
}
public static boolean recursion(int y) {
if(y%10==1 || y%10==2 || y%10==3) {
return true;
}
else if(y%10==0) {
return false;
}
else {
int remain=y/10;
recursion(remain);
}
}
So my approach is quite simple, I used a simple bool recursion to return true or false, true if it does contain 1 2 or 3 and false if not. The problem I am having is that I am not returning anything in my recursion else statement. I know I have to return something but not sure what to return or if its necessary. Anything I can change to make this work?
Your base cases for recursion are a little off, so in the statement
else if(y%10==0), the number 100 would cause this to fail even though it is valid. you want your false base case to actually be else if (y == 0) which means you have gone through the entire number. the solution looks like:
public static boolean recursion(int y) {
int positive = Math.abs(y);
if(positive%10==1 || positive%10==2 || positive%10==3) {
return true;
} else if (positive == 0) {
return false;
}
return recursion(positive / 10);
}
edit: Calling absolute value on the number makes it work for negative numbers as well, but you can call abs on the integer being passed in to the same effect.
I think you just have to do
return recursion(remain);
Use below code, hope this will help.
public static boolean recursion(int y) {
if(y%10==1 || y%10==2 || y%10==3) {
return true;
}
else if(y%10==0) {
return false;
}
else {
int remain=y/10;
return recursion(remain);
}
}

Given three numbers as input,return true if at least one of them is a prime number

Given three numbers as input, return true if at least one of them is a prime number. For solving this problem, define a function that checks whether a number is a prime or not and use that function
MyApproach:
I made a function that checks first whether the num is prime or not(CHECK PRIME).After checking the 3 numbers,if in that function any of the number is prime it should return true
otherwise false.
But I am getting wrong Ans for the test case
Below is my Code:
public boolean anyonePrime(int num1, int num2, int num3)
{
boolean b1=checkPrime(num1);
boolean b2=checkPrime(num2);
boolean b3=checkPrime(num3);
if((b1==true) ||(b2==true) ||(b3==true)) //#Edit
return true;
else
return false;
}
public boolean checkPrime(int num)
{
boolean b0=true;
if(num==1)
return false; //#Edit
else
{
for(int i=2; i<=num/2; i++)
{
if(num % i==0)
{
return false; //#Edit
}
}
return true;
}
if(b0==true)
return true;
else
return false;
//write your code here
}
}
# Edit passes all test cases
For the Input
Parameters ActualOutput Expected Output
'169' '361' '529' true false
The main issue is that b0=true always. But..
it is also rather inefficient as you don't stop immediately if the first one is prime,
nor do you stop immediately if there is a divisor,
nor do you stop when you reach the square root of num
also b3=true which should be b3==true.
You appear to have a typo in your code. You set b0=true; before checking if(b0==true);, so it will always return true. The simple thing to do would simply be to return false as soon as any check finds it is not prime, rather than setting b0 to false and then continuing to do more work.
Try this:
public boolean anyonePrime(int num1, int num2, int num3)
{
return (checkPrime(num1) || checkPrime(num2) || checkPrime(num3))
}
public boolean checkPrime(int num)
{
boolean b0=true;
if(num==1)
b0=false;
else
{
for(int i=2; i<=num/2; i++)
{
if(num % i == 0)
{
b0=false;
}
}
}
if(b0==true)
return true;
else
return false;
//write your code here
}
}
I just removed the 'b0 = true line' and tidied up some code

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

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.

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;

Categories

Resources