Using recursion in java for a palindrome question on leetcode - java

I debugger code shown below, and every thing looks find until "returns true". It does not return immediately, instead it went back somehow. However, I do not assign value when I call the method itself.
I think if I try to use while, it would be much simpler after I finish the recursion.
Could anyone please help me figure out the bug?
Thanks in advance!
class Solution {
public boolean isPalindrome(String s) {
s = s.toUpperCase();
return isPalindromeHelper(s, 0, s.length() - 1);
}
public boolean isPalindromeHelper(String s, int first,int last) {
if(first >= last) {
return true;
} else {
char chead = s.charAt(first);
char ctail = s.charAt(last);
if(!Character.isLetterOrDigit(chead) || !Character.isLetterOrDigit(ctail)) {
if(!Character.isLetterOrDigit(chead)) {
first++;
}
if(!Character.isLetterOrDigit(ctail)) {
last--;
}
isPalindromeHelper(s, first, last);
}
else if(chead != ctail) {
return false;
}
}
first++;
last--;
return isPalindromeHelper(s, first, last);
}
}

I see nothing wrong with your code. It appears to work fine. You may want to
change the following to include a return on the method call.
if(!Character.isLetterOrDigit(ctail)) {
last--;
}
return isPalindromeHelper(s, first, last); // <- added return
If you can explain where you think any problem is I will try to help.

Related

Valid Palindrome [duplicate]

This question already has answers here:
Check string for palindrome
(42 answers)
Closed 2 years ago.
Problem is to check if the string is valid palindrome or not. Return true for empty strings.
What's the problem with my code? It is failing for the input "ab"
public class Solution {
Boolean b;
public Boolean isPalindrome(String s) {
s = s.toLowerCase();
s = s.replaceAll("[^a-zA-Z0-9]","");
if(s.length()==1 || s.isEmpty())
{
return true;
}
for (int i=0;i<s.length()-1;i++)
{
b = expandAroundCenter(s,i,i+1);
b = expandAroundCenter(s,i,i);
}
return b;
}
public Boolean expandAroundCenter(String s,int start,int end)
{
while(start>=0 && end<s.length() )
{
if ((s.charAt(start))!=(s.charAt(end)))
{
return false;
}
start--;
end++;
}
return true;
}
}
You've got big logic flaws here.
Firstly, in your for loop you call expandAroundCenter twice, and overwrite the first results.
Secondly, you're doing this in a for loop, and overwriting all previous results.
Also I think you're making things harder than they need to be by starting in the middle. Start on the edges, and work inward!
Calculating a palindrome is a great opportunity for a recursive function (one that calls itself). I'll give you the pseudo-code, it's up to you to implement:
public Boolean IsPalindrome(string s)
// If we are down to 1 or zero characters, success!
// This deals nicely with odd numbered length strings
if(length <= 1)
return true;
// If the first and last don't match, it's not a palindrome
if(first letter != last letter)
return false;
// Since we know the first and last match, strip them off, then repeat
return IsPalindrome(strip first and last letter from string)
}
If there are no constraints, the best way to solve this problem is to use recursive.
class palindrome
{
static boolean isPalRec(String str,
int s, int e)
{
if(s == "")
return true;
if (s == e)
return true;
if ((str.charAt(s)) != (str.charAt(e)))
return false;
if (s < e + 1)
return isPalRec(str, s + 1, e - 1);
return true;
}
static boolean isPalindrome(String str)
{
int n = str.length();
if (n == 0)
return true;
return isPalRec(str, 0, n - 1);
}
}

How to correctly place a return statement in a recursive method with if\else conditions

I'm writing recursive code that is build with if\else controlling the return statements. However when I compile, I get a 'missing return statement' because all of my returns are in the conditions. I'm adding 'fake' returns(to which the method should never reach) but I was wondering if there is a smarter solution.
for example:
private static boolean compare(int[][] a, int i) {
if (i == a.length - 1) {
return true;
}
else {
if (calcLineSum(a[i], 0, 0) == calcLineSum(a[i + 1], 0, 0)){
compare(a, i + 1);
}
else {
return false;
}
}
return false; //<= = 'fake'
}
private static int calcLineSum(int[] a, int i, int sum) {
if (i == a.length)
return sum;
else {
sum = sum + a[i];
calcLineSum(a, i + 1, sum);
}
return sum; //<= = 'fake'
}
thank you very much for your input!
I think if you replace compare(a,i+1); with return compare(a,i+1); and calcLineSum(a,i+1,sum); with return calcLineSum(a,i+1,sum); it should compile.
Every if and else if should be terminated with a return.
First off; indent your code properly and add braces to all of your conditions. It will seriously save you hours of debugging.
When its properly formatted its easy to spot the error:
private static boolean compare (int[][]a, int i)
{
if(i==a.length-1)
{
return true;
}
else
{
if(calcLineSum(a[i],0,0)==calcLineSum(a[i+1],0,0))
{
compare(a,i+1);
}
else
{
return false;
}
}
return false; <=='fake' return
}
You can clearly see the statement compare(a,i+1); is missing the return. Happy debugging!
It looks like you misunderstand return. In your code
private static int calcLineSum (int[]a, int i, int sum)
{
if(i==a.length)
return sum; // only returns `sum` from this one invocation,
// *not* further up the recursive chain
else {
sum=sum+a[i];
calcLineSum(a,i+1,sum);
// your code is **still going** here; the `return` from
// the recursive call didn't change anything
// also note that `sum` hasn't actually changed here
// sum is passed by value, and changes to it inside the recursive call
// don't actually make any difference out here
}
return sum; // actually used
}
It looks like the correct implementation would be
private static int calcLineSum(int[] a, int i, int sum) {
if (i == a.length) {
return sum;
} else {
return calcLineSum(a, i+1, sum + a[i]);
}
}
Try this approach:
private static boolean compare (int[][]a, int i) {
boolean result = false;
if (i == a.length-1) {
result = true;
} else {
if(calcLineSum(a[i],0,0) == calcLineSum(a[i+1],0,0)) {
result = compare(a,i+1);
}
}
return result;
}
private static int calcLineSum (int[]a, int i, int sum) {
int result = sum;
if (i != a.length) {
result = calcLineSum(a,i+1,sum+a[i]);
}
return result;
}
The issue here is that a method with a non-void return type must be guaranteed to return a value of that type.
Ignoring the specific code, the structure of your compare method is basically:
if() {
return
} else {
if () {
// you don't return anything here,
// so the method might not do what you promised it would,
// namely return a value
} else {
return
}
}
If there is any way the method can run that won't return a value, the compiler will call you out on it.
Your recursion:
private static int calcLineSum (int[]a, int i, int sum)
{
if(i==a.length)
return sum;
else {
sum=sum+a[i];
calcLineSum(a,i+1,sum);
}
return sum; //<=='fake' return
}
You can do it pretty well like this:
private static int calcLineSum (int[]a, int i, int sum)
{
if(i==a.length)
return sum;
sum=sum+a[i];
calcLineSum(a,i+1,sum);
}
All I did was remove the else. If the first condition isn't met, with or withou the else, you will execute these two lines:
sum=sum+a[i];
calcLineSum(a,i+1,sum);
It simplifies your code too.
In addition, you can remove the line
sum=sum+a[i];
writing like this:
private static int calcLineSum (int[]a, int i, int sum)
{
if(i==a.length)
return sum;
calcLineSum(a,i+1,sum+a[i]);
}
with out your last return statement (the ones you call fake); there are indeed condition that do not return anything;
For example in your first method if the following condition is satisfied nothing will be returned :
if (calcLineSum(a[i], 0, 0) == calcLineSum(a[i + 1], 0, 0))
similarly for your second method your else block do not return anything.
as a good coding practice please use { } arround if and else block.

Is it possible to write return statement in if block using java?

I want to return Vector according to if block but the code gives me the following error: Add return statement.
Is it possible to write return statement in if block?
public static int[] zeroVectorBinning1( ImageFloat32 angle,ImageFloat32 Magnitude )
{
for (int NumberOFChanks=0;NumberOFChanks<locations_original.size();NumberOFChanks++)
{
for(int i=0;i<angle.getHeight();i++)
for(int j=0;j<angle.getWidth();j++)
{
int orientaionVal=(int) angle.get(j, i);
if(orientaionVal<=0)
{int magnitudeVal=(int) Magnitude.get(j, i);
int[] Vector = new int[19];
Vector=zeroVector(19);
Vector[0]=magnitudeVal;
return Vector;
}
else if(orientaionVal<=20)
{int magnitudeVal=(int) Magnitude.get(j, i);
int[] Vector = new int[19];
Vector=zeroVector(19);
Vector[1]=magnitudeVal;
return Vector;
}
else(orientaionVal >= 0 && orientaionVal <=20)
{
int magnitudeVal=(int) Magnitude.get(j, i);
int[] Vector = new int[19];
Vector=zeroVector(19);
Vector[0]=magnitudeVal;
Vector[1]=magnitudeVal;
return Vector;
}
}
}
}
There's nothing wrong in having return statements in if blocks, but your method must have a return statement in any execution path.
Your for loops may never be executed (if, for example, locations_original.size() is 0), in which case none of the if blocks that contain the return statements will be reached. Therefore you must add a return statement following the loops.
Yes,
But your function still not return anything in the end, so you have to return something, even null.
So when you call this function, it should ne looking like this:
int[] fuctionResult = zeroVectorBinning1(....);
if (fuctionResult != null){
....
}
You could resolve this in two ways:
At the end either throw an exception just before completing the method.
Or at the end just return null.
Reason why compiler is complaining because, if locations_original.size() returns 0 then this method would never return anything which contradicts with what you said in your method that it will return an int array.
It is possible. But you need a return statement for every cases. Also if your for loop is never executed.
so add return null; at the end of your method.
Yes it is possible. Follow the code snippet for explanation.
public class TestSample {
public static void main(String... w){
int h = new TestSample().call();
System.out.println(h);
}
public int call(){
int j =0;
for(int i=0;i<10;i++){
if(i==5){
return i;
}
}
return j;
}
}
This prints 5.
public int getValue(){
final int value = 3;
if(value==1){
return 1;
}
else if(value==2){
return 2;
}
else if(value==3){
return 3;
}
else{
return -1;
}
// no return because "else" covers all cases
}
In this case you have an "else" at the end, so every case is covered. but if you leave the else ...
public int getValue(){
final int value = 3;
if(value==1){
return 1;
}
else if(value==2){
return 2;
}
else if(value==3){
return 3;
}
return -1;
// ... you have to return something at the end of the method, because value could be >3 or < 1 and the code under the last else if will be executed
}
The problem is your if/else-if/else parse is not complete, what does else with a condition like:
else(orientaionVal >= 0 && orientaionVal <=20)
mean? It's odd. Just omit the condition (orientaionVal >= 0 && orientaionVal <=20) of the last else sentence (and it's not logically correct when orientaionVal is 0 or 20), or there will be no default else in the scope.
When return in the scope of a if sentence, we must make sure that under any condition there is a return, so:
Make a default return out of the if-else scope
Or be sure that the condition judgement is complete and there is a return under any condition.
So
Correct:
if(condition){
return;
}
return;
Correct:
if(condition){
return;
}else if(anotherCondition){
return;
}else{
return;
}
Wrong:
if(condition){
return;
}
// no return ...
Wrong:
if(condition){
return;
}else if(anotherCodition){
return;
}
// no return ...

difference in else if {.. and else { if(

I recently got coursework back and was award 0 marks for some stupid reason and I checked someone in my classes and this is my code:
public static String take(String s, int n) {
while(true){
if(s.equals("")){
return "";
} else if(s.length() < n){
return s;
} else {
return s.substring(0,n);
}
but his is
public static String take(String s, int n) {
while (true) {
if (s.equals("")) {
return "";
} else {
if (s.length() < n) {
return s;
} else {
return s.substring(0, n);
}
}
}
}
I was wondering is there a difference in
else if{...}
and
else{
if{ }
}
Our code does EXACTLY the same..
No, there is no difference. You can do it either way.
There is technically no difference, it's a matter of code style.
But keep in mind that in case of multiple else if, you may end up with a messy indentation :
if(test1) {
...
} else {
if(test2) {
...
} else {
if(test3) {
...
} else {
if(test4) {
...
}
}
}
}
instead of the cleaner :
if(test1) {
...
} else if(test2) {
...
} else if(test3) {
...
} else if(test4) {
...
}
No, there is no difference at all in its working. But, you can have multiple else if blocks consecutively, but not multiple else blocks consecutively with if inside it
There is no difference.
You can do it in both ways.
In most cases I encourage people to use braces wherever they can; that is never to use:
if(x) y = z;
and always to use:
if(x) {
y = z;
}
However, "if else" is a solid idiom, so it's the exception to that rule:
if(x) {
...
} else if(y) {
...
} else {
...
}
... is well formatted code, and is equivalent to:
if(x) {
...
} else {
if(y) {
...
} else {
...
}
}
... which is messier, and has scope for misplaced braces which change the logic.
else if has no special meaning in Java. It's an else part whose statement is an if statement; and one must take into account that since the else part is not a block enclosed in curly braces, the else part has only one statement. So you could indent your example like this, to see it more clearly:
if(s.equals("")){
return "";
} else
if(s.length() < n){
return s;
} else {
return s.substring(0,n);
}
while the other example looks like
if (s.equals("")) {
return "";
} else {
if (s.length() < n) { // the second if statement starts here
return s;
} else {
return s.substring(0, n);
} // the second if statement ends here
}
which is just the same, except for the extra braces around the second if statement.
But although else if is not special, as others have said, it's common enough that programmers follow different indentation and { } conventions when using it, especially since sometimes there can be many of them chained together. (In fact, in languages like Perl that don't allow else if without a curly brace after the else, or Ada which requires end if at the end of each if, the idiom is so indispensable that they added a special keyword elsif to allow programmers to use it.)
No there is no difference technically but good practice to use else if {}

My code won't return anything! output is simply blank

I'm writing this code in java to scan numerical or alphabetical strings to see if they are consecutive. Everything seems to be working fine until I try to place a boolean in there to return true or false but nothing is happening! What am I missing? THanks! :)
Here it is:
public class Question1 {
public static void main(String[]args){
String s = "gFeD";
isConsecutive(s);
}
public static boolean isConsecutive(String s){
boolean letters;
letters = false;
int counter = 0;
String newS = s.toLowerCase();
for (int i = 0; i < newS.length() - 1; i++){
if (newS.charAt(i) - newS.charAt(i+1) == 1){
return true;
} else if (newS.charAt(i) - newS.charAt(i+1) == -1) {
return true;
}
}
return letters;
}
}
for (int i = 0; i < newS.length() - 1; i++){
if (newS.charAt(i) - newS.charAt(i+1) == 1){
return true;
} else if (newS.charAt(i) - newS.charAt(i+1) == -1) {
return true;
}
this is not what you're after.
You don't want to return true from within the for loop. Not unless you find that the order is not maintained. Else you'll return too early. On the other hand returning false is OK, again if you find that the order is in fact off.
You don't want to check if char - otherchar == 1 or -1 as that's too restrictive. You want to look at > 0 or < 0.
You're not doing anything with the return value. If you want to see it on the console, do System.out.println(isConsecutive(s));. That's why "nothing is happening". It's running properly as you wrote it; it just doesn't produce any visible output.
Just replace last line from main method with System.out.println(isConsecutive(s));. This should work.
You are not printing anything, try System.out.println(isConsecutive(s));

Categories

Resources