You also ask if we can do better than stepping through every number in the range and testing to see if it is a stepping number. Certainly we can. We can generate the stepping numbers by composition. We don't have to search for them. I notice that this is described in more detail on Stack Overflow Stack Overflow.
You also ask if we can do better than stepping through every number in the range and testing to see if it is a stepping number. Certainly we can. We can generate the stepping numbers by composition. We don't have to search for them. I notice that this is described in more detail on Stack Overflow.
You also ask if we can do better than stepping through every number in the range and testing to see if it is a stepping number. Certainly we can. We can generate the stepping numbers by composition. We don't have to search for them. I notice that this is described in more detail on Stack Overflow.
public void steppingNumber(int s, int e) {
As described in the problem statement, s
is the starting number and e
is the ending number. Why not call them start
and end
then? That way we don't have to refer to the problem statement to know what the variables mean.
I would also pick another name for the function. You are printing the stepping numbers, so call it printSteppingNumbers
. As a general rule, functions should have verb names. They do things and their names should reflect that.
String str = String.valueOf(s);
Why a string? In C, this would make sense as the difference between a letter and a number in C is trivial (char
is an integer type). Java isn't as forgiving. Even if you do want a string, this is the wrong place to do it. Call the function with s
(or start
).
if ( isSteppingNumber(start) ) {
System.out.print(start + " ");
}
I added braces ({}
) around the then clause. This helps avoid a class of error where someone intends to add a new statement to the then clause but actually makes it run whether the if
triggers or not. I also find it easier to read.
List<String> numbers = new ArrayList<>();
while(str.length() >= 3) { // get every 3-digit comma-separated number
numbers.add(str.substring(str.length()-3));
str = str.substring(0,str.length()-3);
}
This seems overly complicated. You don't need to generate a List
here. It's sufficient to check each chunk as you go through.
while ( str.length() > 3 ) {
if ( ! isSteppingSequence(str.substring(str.length()-3)) ) {
return false;
}
str = str.substring(0,str.length()-3);
}
return isSteppingSequence(str);
You also don't need >=
here. A simple >
is better, as you always want there to be one chunk left to test outside the loop.
But we can do better if we keep it as a number at this point. First, we need a constant.
private final static int CHUNK_SIZE = 1000;
Now we can use it.
while ( number > CHUNK_SIZE ) {
if ( ! isSteppingSequence(number % CHUNK_SIZE) ) {
return false;
}
number /= CHUNK_SIZE;
}
return isSteppingSequence(number);
Another constant.
private final static int BASE = 10;
Now we just need to define isSteppingSequence
and we get:
private final static int BASE = 10;
private final static int CHUNK_SIZE = 1000;
private static void listSteppingNumbers(int start, int end) {
while ( start <= end ) {
if ( isSteppingNumber(start) ) {
System.out.print(start + " ");
}
start++;
}
}
private static boolean isSteppingNumber(int number) {
if ( number < BASE ) {
return false;
}
while ( number > CHUNK_SIZE ) {
if ( ! isSteppingSequence(number % CHUNK_SIZE) ) {
return false;
}
number /= CHUNK_SIZE;
}
// all the other sequences were stepping, so
// if this one is, it's a valid stepping number
// otherwise not
return isSteppingSequence(number);
}
private static boolean isSteppingSequence(int number) {
int previous_digit = number % BASE;
number /= BASE;
while ( number > 0 ) {
int current_digit = number % BASE;
if ( Math.abs(previous_digit - current_digit) != 1 ) {
return false;
}
previous_digit = current_digit;
number /= BASE;
}
// if number was less than BASE, then it skipped the while loop
// and all single digit numbers are valid stepping sequences
// so true
// if it made it through the while loop,
// all the adjacent digits differed by 1
// so true
return true;
}
So we now have a more readable version of your initial algorithm. Since it doesn't convert to a String
and from characters, I suspect that it will be slightly faster.
You also ask if we can do better than stepping through every number in the range and testing to see if it is a stepping number. Certainly we can. We can generate the stepping numbers by composition. We don't have to search for them. I notice that this is described in more detail on Stack Overflow.