Leetcode #9 Discussion: Only one integer to solve it.

I solved #9 with one integer finally and the time complexity is O(n). 
It's really interesting so I want to record my thinking process.

Leetcode #9 Discussion // Rewrite in Markdown mode. 16/9/13

Initial Solution

  • It’s easy to start this problem with this formula:
    这里写图片描述
  • Then you could get it:
    这里写图片描述
  • With this formula, you could easily solve this problem like what I did in my last article, at that time, I use 5 variables to solve it:
    int i; //Loop variable for computing X's length and comparing digits
    int j; //Record the length of X
    int t; //Loop variable to compute 10^i
    int l; //Record 10^i
    int a; //Record X[i] when compare X[i] and X[j-i+1]
  • 5 varaibles and O(n^2). More details in my last article.

Improvement. 3 variables to solve it

  • Compute 10^i again and again makes this code O(n^2) and you have to record it by a variable. So try to improve it.
  • Try to start the loop at the middle digit of the number.
  • For odd number:
    这里写图片描述
  • For even number:
    这里写图片描述
  • Now, compute 10^(n/2) first, we don’t need to compute 10^i every time, you could also remove variable l and variable a, because you don’t need to record 10^i and Xi.
  • So, 3 variables and O(n) to solve it, code below:
    bool isPalindrome(int x) 
    {
        if(x<0) return false;
        int i,j,t;
        i=x; j=0;
        while (i) { j++; i/=10;}
        if (j % 2==0)
        {
            t=1; j/=2;
            for (i=1;i<=j;i++)t*=10;
            i=10;
            while (j)
            {
                if (j==1)
                {
                    if (x%(t/i*10)/(t/i)!=x/(t/10*i)) return false; 
                } else
                {
                    if (x%(t/i*10)/(t/i)!=x%(t*i)/(t*i/10)) return false;   
                }
                j--; i*=10;
            }
        } else
        {
            t=1; j/=2;
            for (i=1;i<=j;i++) t*=10;
            i=10;
            while (j)
            {
                if (j==1)
                {
                    if (x%(t/i*10)/(t/i)!=x/(t*i)) return false; 
                } else
                {
                    if (x%(t/i*10)/(t/i)!=x%(t*i*10)/(t*i)) return false;
                }
                j--; i*=10;
            }
        } 
        return true;
    }

Final version. Make a new start

  • In the method above, we use this formula to solve the problem:
    这里写图片描述
  • This formula is really complex because we keep X unchanged. In fact, these is no need to do like this. Can we simplify this formula by changing X?
    这里写图片描述
  • Look at the picture above. If we could remove the first digit and the last digit of X after each step, we could compare X0 and Xn by these formulas.
  • It’s easy to work out, and I tried with 2 variables at first.
   bool isPalindrome(int x) 
    {
        if (x<0) return false;
        int i=1,j=x;
        while (x>=10) {x/=10; i*=10;}
        x=j; 
        while (x>=10)
        {
            if (x % 10 != x / i) return false;
            else 
            {
                x/=10; i/=10; 
                x%=i;  i/=10;
            }
        }
        return true;
    }
  • However, it can’t pass.
  • ‘X>=10’ was used to end the loop, but if you try a number like X=200012, the answer will be TRUE.
  • ‘200012’, after you delete the first digit and last digit of this number, it changes to ‘1’. Then ‘X>=10’ is not satisfied so the loop goes to end.
  • So the point is you need to control the length of number. The program need to know ‘1’ is ‘0001’ in fact.
  • While this information is actually hidden in the code.’int i’ in the code is equal to ‘10^n’ at first. After each step, you deleted the first and the last digit, and n(the length of number) minus 2, so i is divided by 100. Wait, it means that ‘int i’ knows the length of X exactly.
  • Up to this point, the algorithm is good enough.2 variables, O(n), short codes.
   bool isPalindrome(int x) 
    {
        if (x<0) return false;
        int i=1,j=x;
        while (x>=10) {x/=10; i*=10;}
        x=j; 
        while (i>1)
        {
            if (x % 10 != x / i) return false;
            else 
            {
                x/=10; i/=10; 
                x%=i;  i/=10;
            }
        }
        return true;
    }
  • However, it could be better. For initializing i, we need j to record x and do division again and again. Think another way, we multiply i rather than divide j, then we can keep x unchanged and j could be removed.
  • Then you get the final version, one integer, O(n), really short codes to solve it.
    bool isPalindrome(int x) 
    {
        if(x<0) return false;
        int j=1;
        while (x/j>=10) j*=10;
        while (j>1)
        {
            if (x/j != x % 10) return false;
            x%=j; x/=10; j/=100;
        }
        return true;
    }

这里写图片描述

FAST!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值