LeetCode数学专栏(简单:1-20)

上一章刷的是数组专栏,这次刷数学专栏。


  1. 整数反转(7)
    LeetCode数学专栏(简单:1-20)_第1张图片
      这种题没什么特别的,就是需要知道这种思想方法:反转利用取余得到末尾的数字(也就是结果的开头),然后循环乘以10,使得它最终到达应该在的首位。
    LeetCode数学专栏(简单:1-20)_第2张图片

  1. 回文数(9)
    LeetCode数学专栏(简单:1-20)_第3张图片
      这道题的进阶是不将数字转化为字符串从而解决它。那么第一种方法显而易见就是将数字转化为字符串,进而求解:
    LeetCode数学专栏(简单:1-20)_第4张图片
      第一种方法显而易见,难点在于不转换为字符串。下面需要多引一个变量z,因为如果用x去作为循环的中间值的话,那么x最后一定为0,我们就不没有了与y比较的原始值了。
    LeetCode数学专栏(简单:1-20)_第5张图片
      下面是转一半的代码,理论上是优化了时间,但是其实数字最长也就32位,循环从32变为16,但是判断增多了,所以实际效果也就没那么明显了。
    LeetCode数学专栏(简单:1-20)_第6张图片

  1. 罗马数字转整数(13)
    LeetCode数学专栏(简单:1-20)_第7张图片
    LeetCode数学专栏(简单:1-20)_第8张图片
      按照题意写出如下代码应该不难(正常情况下res直接加上符号对应的值即可,当前面的符号小于后面的符号,那么就减去2倍的前面的符号对应的值(因为在这之前,已经加过一次了))。
    LeetCode数学专栏(简单:1-20)_第9张图片
     补充一个Js的知识点:数组也可以是下面这种形式(并不是对象,前面的变量只是代替了数组下标)。访问的时候直接点出来即可。
    在这里插入图片描述
    在这里插入图片描述
      于是按照数组的形式写出来的代码如下:
    LeetCode数学专栏(简单:1-20)_第10张图片
      其实这里还可以计算所有的字母出现的次数,然后使用一个set去存字母出现的次数(当然,当小值字母排在大值字母前面的时候,小值字母次数-2)。

  1. 二进制求和(67)
    LeetCode数学专栏(简单:1-20)_第11张图片
      这道题的解决思路目前我想到的只有一步一步计算。
    LeetCode数学专栏(简单:1-20)_第12张图片
      需要注意的是字符串的值是无法改变的,只能新增、翻转、删除等。还有就是在处理最后最后一次进位问题上,需要注意判断最后carry是否等于1,如果等于1,那么字串符长度应该比原来两个字符串最大长度还要多一位。
    在这里插入图片描述

  1. x的平方根(69)
    LeetCode数学专栏(简单:1-20)_第13张图片
      这道题的第一种方法可以使用折半查找,因为最终求得的结果一定在0到x之间,并且每次可以通过缩减一半的区间来提升效率。
    LeetCode数学专栏(简单:1-20)_第14张图片
      其实根据我们的经验,一个数的平方根一定是小于等于这个数的中间值的。(除了1),所以我们可以设置right等于中间值+1,来照顾到1的存在。
    在这里插入图片描述
      在翻看答案的时候看到还有一种解法:牛顿迭代法

在迭代过程中,以直线代替曲线,用一阶泰勒展式(即在当前点的切线)代替原曲线,求直线与 xx 轴的交点,重复这个过程直到收敛。

牛顿法的两个重要应用是:求方程的根、求解最优化问题。
详情可以参考:https://blog.csdn.net/batuwuhanpei/article/details/51979831
LeetCode数学专栏(简单:1-20)_第15张图片
LeetCode数学专栏(简单:1-20)_第16张图片


  1. Excel表列名称(168)
    LeetCode数学专栏(简单:1-20)_第17张图片
    LeetCode数学专栏(简单:1-20)_第18张图片
      这道题我提交失败了好几次,原因在于我没有考虑到循环中if(n%26===0)的情况,也就是26的整数倍的时候,应该输出’Z’。并且n需要多减去1。
    LeetCode数学专栏(简单:1-20)_第19张图片
      简化后的代码如下:
    LeetCode数学专栏(简单:1-20)_第20张图片

  1. Excel表列序号(171)
    LeetCode数学专栏(简单:1-20)_第21张图片
    LeetCode数学专栏(简单:1-20)_第22张图片
      这道题是上一道的反解。原理比较简单:以三位为例,sum = 26 ^ 2s[2]+26 ^ 1s[1]+26 ^ 0*s[0]。
    LeetCode数学专栏(简单:1-20)_第23张图片

  1. 阶乘后的零(172)
    LeetCode数学专栏(简单:1-20)_第24张图片
      这道题一开始我是想着循环从0到给定数字,然后找其中的5,有几个5结果就有几个0。后来我发现24 * 25的时候,会出现两个0。仔细思考之后,发现25等于5 * 5,也就是说25里面“藏着”2个5,所有会出现两个0。这样的话,我再内层循环需要加上对5 * 5=25、5 * 5 * 2=50、5 * 5 * 5=125这类数字进行找5的工作。代码如下:
    LeetCode数学专栏(简单:1-20)_第25张图片
      很遗憾,提交的结果是超出时间限制。时间复杂度达不到logn,貌似看起来像是n?(我自己的理解是内层的循环次数为常数,所以是n)。
    LeetCode数学专栏(简单:1-20)_第26张图片
      经过改进,代码通过。其实可以只根据题目给的n,就可以算出最后的答案。具体做法是,用n除以5,取余数加到结果上;再对余数作除法,循环下去,最后直到n小于5(得不到大于1的余数)。比如100;100/5=20,这个20就代表从0开始到100每10个数中有两个0(比如0-10中,2*5和10);20/5=4,这个4代表0-100中有4个能继续被5除的数,有25、50、75、100。比如25/5=5,得到的结果除5,等于1。
      方法3,这道题还可以使用递归做法,其实也是同理,代码如下:
    LeetCode数学专栏(简单:1-20)_第27张图片

  1. 快乐数(202)
    LeetCode数学专栏(简单:1-20)_第28张图片
      这道题我一开始的思路就是递归,然而这很容易面临一个问题,就是递归调用栈超出最大限制,如下图:
    在这里插入图片描述
    LeetCode数学专栏(简单:1-20)_第29张图片
      无奈没想出一个好的解决方法。看了别人的Solution,学会了一种新的思想方法:“快慢指针”。设置一个慢指针,初值为n,再设置一个快指针,初值为bitSquareSum(n),慢指针每次向前走一步,快指针每次向前走两步。这样,假设n为快乐数,并且可以经过4步走到结果1,当慢指针走4步到达终点的时候,快指针刚好经过8次调用(每次2步)到达终点,此时slow===fast。假设n不是快乐数,比如2,那么他会陷入一个循环,但是始终到达不了1,如下图。那么最终slow一定会等于fast(如2,slow和fast会在7次之后于42处相遇-----42是数字循环的尾数)。
    LeetCode数学专栏(简单:1-20)_第30张图片
    LeetCode数学专栏(简单:1-20)_第31张图片

  1. 计数质数(204)
    LeetCode数学专栏(简单:1-20)_第32张图片
      我的第一反应是下面这种方法,但是超出时间限制。
    LeetCode数学专栏(简单:1-20)_第33张图片
    LeetCode数学专栏(简单:1-20)_第34张图片
      这道题用到了厄拉多塞筛法,具体方式是通过排除n以内的素数来得到质数的数量。遍历2到n/2-1;每次循环排除当前数字的倍数。比如计算100以内质数数量,只需要遍历2到100。遍历2的时候,将100以内2的倍数全部排除,遍历3的时候,将100以内3的倍数全部排除,以此类推,每次遍历的数字不包括已被排除的数字,所以我们需要建立一个数组来存储已被排除的数字。
    LeetCode数学专栏(简单:1-20)_第35张图片
      上述代码可读性可能不太好,提高代码可读性后的代码如下:
    LeetCode数学专栏(简单:1-20)_第36张图片

你可能感兴趣的:(算法)