Strobogrammatic Number III

A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down). Write a function to count the total strobogrammatic numbers that exist in the range of low <= num <= high. For example, Given low = "50", high = "100", return 3. Because 69, 88, and 96 are three strobogrammatic numbers.

Note: Because the range might be a large number, the low and high numbers are represented as string.

Solution

public class Solution {

 char[] singles = new char[]{'0','1','8'};
 // Sorted by the first char in ascending order
 char[][] pairs = new char[][]{ {'0','0'},{'1','1'},{'6','9'},{'8','8'},{'9','6'} };
 char[] ans; // buffer of storing the number
 int count = 0; // total count
 char[] l; // char array of low
 char[] h; // char array of high

 // Compare two numbers' char array. Longer one is the larger one.
 // If have same length then compare each char from left to right
 // return positive when s2 > s1, 0 when s2==s1, nagetive when s2 < s1
 int comp(char[] s1, char[] s2) {
     int len1 = s1.length;
     int len2 = s2.length;
     if (len1 != len2) return len2-len1;
     else {
         for (int i=0; i < len1; i++) {
             if (s1[i] != s2[i]) return s2[i]-s1[i];
         }
         return 0;
     }
 }
 // Recursion for generating Strobogrammatic numbers of length n 
 // starting from both ends. As a result, the numbers are 
 // generate in ascending order.
 // Therefore, when when a number is greater than high it returns false 
 // and then terminate the loop. 
 boolean helper(int n, int s, int e, int len) {
     if (n==0) return false;
     if (len==n) { // a resulting number 
         // checking the range
         if ( comp(l, ans) >=0  && comp(ans, h) >=0 ) count++;
         if ( comp(ans, h) < 0) return false; // the nubmer is greater than high
         return true;
     } else if (s==e) { // odd length at the middle position, apply single digit
         for (int i =0 ; i< singles.length; i++) {
             if ( ! ( s == 0 && i == 0 && n > 1)  ) { // first digit can't be 0
                 ans[s] = singles[i];
                 if ( ! helper( n, s+1, e-1, len+1) ) return false;
             }
         }
     } else { // placing two digits at both ends
         for (int i =0 ; i< pairs.length; i++) {
             char[] pair = pairs[i];
             if ( ! ( s == 0 && i == 0)  ) { // first digit can't be 0
                 ans[s] = pair[0];
                 ans[e] = pair[1];
                 if ( ! helper( n, s+1, e-1, len+2 ) ) return false;
             }
         }
     }
     return true;
 }
 // counting the total Strobogrammatic numbers of lengh n 
 // without considering the range
 int counts(int n, int next) {
     if (next<=0) return 0;
     if (next==1) return 3;
     if (next==2) return n==next? 4 :5; // first digit can't be 0
     return n==next? 4 * counts(n, next-2) : 5 * counts(n, next-2);
 }

 public int strobogrammaticInRange(String low, String high) {
     int low_len = low.length();
     int high_len = high.length();
     l = low.toCharArray();
     h = high.toCharArray();
     for (int i=low_len; i <= high_len; i++) {
         // generating the numbers only when the length is equal to low or high
         if (i== low_len || i== high_len) {
             ans = new char[i];
             helper(i, 0, i-1, 0);
         } else { 
             // counting the total numbers without acctualy generating them
             count+=counts(i,i);
         }
     }
     return count;
 }
}

results matching ""

    No results matching ""