笔试题63. LeetCode OJ (50)

这个题让我们自己实现一个 pow(x,y) 函数,看起来简简单单的一个函数,我相信绝对可以难倒一片人的,因为我们很难将它"写对"。我之前其实也见过这个题的,在剑指offer上就出现过了,我感觉我写这个算法没有问题的,我考虑了很多方面而导致程序看起来比较的乱,最终修改了好几次才正确。

我个人感觉这个题比较重要的一点是 pow(x,y) 的功能的处理比凸显代码能力吧,首先比如: pow(3,10) 难道我们要使用循环10次的方法一个一个的乘吗?当然不能这样我给你个 pow(3,1000) , pow(3,10000) 这些难道我们都是用循环一个一个的乘?显然不是。

另外我在提交的时候发现了一个问题,就是当指数为 -2147483648 的时候,我们该怎么处理这种情况呢?我当时没有考虑这个问题的,但是提交的时候暴露出来了,例如 pow(-1,-2147483648) ,它的结果是多少呢? 答案是 1 ,而pow(2,-2147483648)
的值为0,但我个人觉得有点不妥(我考虑的是int类型的范围),大家也可以提出质疑。我在代码中给出了一些注释,可以看出来哪些细节需要注意,大家可以参考一下。

class Solution {
public:
	double myPow(double x, int n)
	{
		/*
		    -2147483648到底算正数还是负数
		    x=-1 n=-2147483648 >> 1
		    x=2  n=-2147483648 >> 0

		*/

        //指数为0,  0^0 = 1
		if (n == 0)
		{
			return 1;
		}

		//注意double与0的比较
		if (x <= 0.00001 && x > (-0.00001) )
		{
			return 0;
		}

        //底数为1或-1
        if(x==-1 || x==1)
        {
            if(n%2==0 && x==-1)
            {
                return -x;
            }
            return x;
        }

        //指数为1
		if (n == 1)
		{
			return x;
		}

		//无效输入的情况,(-3)^(-3)无效
		if (n < 0 && x < 0 && n % 2 != 0)
		{
			return 0;
		}

		if (n == (int)pow(2,31))
		{//底数不为1或-1的时候,该值的结果应该返回0,但是个人感觉该值没有什么意义
			return 0;
		}

		double value = 0;
		bool isminusN = false;	//指数的正负

		if (n < 0)
		{// n为负数
			isminusN = true;
			n *= -1;
		}

        //获取指数运算的结果
		value = getNum(x, n);

		//n为偶数时
		if (isminusN)
		{//指数为负数
			return 1 / value;
		}
		else
		{//指数为正数
			return value;
		}
	}

	double getNum(double x,int n)
	{
		if (n == 1)
		{
			return x;
		}
		if (n == 2)
		{
			return x*x;
		}
		return getNum(x, n / 2)*getNum(x, n - (n / 2));
	}
};

最后的结果是通过了,这种题给我们的启示就是我们需要很细心的去思考,并注意一些易错的问题。

时间: 2024-08-07 21:09:32

笔试题63. LeetCode OJ (50)的相关文章

笔试题76. LeetCode OJ (63)

Unique Paths II     这次还是机器人在最左上角,想要到达最右下角,机器人能走的方向还是向下和向右,但是与上次不同的是:路上有障碍物,有障碍物的地方不能通过,找出所有独一无二的路径. 上个题的解题思路我自己好像也没什么算法根据,凭借的是自己观察问题找到的,不过这个题我还是按照那样的想法去做的话,确实没想通,我试了一下,发现代码很复杂而且没有把握,所以我换了种思路,我借鉴了一下网友的,主要是为了弄明白这个题属于哪一类问题,它是动态规划类的问题! 首先,我们可以得出这样一个结论:机器

笔试题28. LeetCode OJ (15)

这个题确实比较复杂,我刚刚开始的思路是先将数组排序,然后从左向右遍历,然后用两个变量lpos,rpos分别指向left+1 和 nums.size()-1,然后求三者的和,若和sum < 0 则让lpos加1,若sum>0则让rpos减1.想法不错,可是现实很残酷.这样 的解很容易错过真实解,我测试了很多遍,总有测试用例无法通过.其中还有一个时间复杂度太高了也没通过测试.这个题大家 可以自己去实现试试,真的错误点太多了,最后还是采用了比较老实的办法,再一步一步分析,求的解如下: class S

笔试题26. LeetCode OJ (13)

哈哈,有了上个题的经验,我们是不是应该趁热打铁呢?这次是讲一个罗曼的(罗马)数字转化为一个整形数字,所以我们逆向去推理上个题,其实这个题很有规律的,将string数组遍历一遍就可以求解了,废话不多说,见代码: class Solution { public: int romanToInt(string s) { //和上道题刚好相反 int lastnum = 0; int len = s.size(); if(len < 1) { return lastnum; } int i = 0; wh

笔试题52. LeetCode OJ (39)

如果还记的话或者写过LeetCode的人会知道,这是nsum,已经不再是之前的twosum,threesum,foursum了.之前是都是使用 i 层循环解题的,那么现在n层循环理论上是可以解题的(其实应该不行),但是n是不确定了,而且是可变的,其变化范围是[1,n] 说道这里其实想说明的是,我们要换种思路去解题了.我在看到这个题的时候想到的思路是: 我们从小到大一个一个将最小的数字重复不断的加入到 vector 中,若vector现有的值的和比 target 大则将 vector 集合中的元素

笔试题73. LeetCode OJ (60)

Permutation Sequence 这个题是求1~n (n[1~9]) 的数字的全排列的第K个序列. 一般思路是:使用一个计数器,递归去找全排列序列,找到一个计数器加一,一直到第k个. 但是加若 n = 9 我要找的是第 (9! -1 )个数,那么上述办法的时间是多少,多半会超时的(没试过,但是我敢保证一定会超时的,因为这样的思路不可取),想一想我们只需要一个序列,并不必要把全部的序列都找出来吧.下面我给出一种解题方案,我个人感觉是可取的. 我们是学过数学的人,要我们求全排列的第 k 个序

笔试题85. LeetCode OJ (71)

              Simplify Path     这个题是给出一个字符串的相对路径,让我们返回绝对路径,让我们在Linux下自己去动手操作确实不难,可是用程序做起来的话确实比较麻烦. 我的解题思路是找好'/'和'.'之间的关系,找好他们之间的组合关系后这个题就容易一些.在路径中'.'和'/'的组合正常的可能只有'.'和'..'两种.'/'是起修饰作用的,说明当前目录下可能还存在目录. 既然我们要写这个题的话,那么肯定会出现各种组合的情况,其实我们只要处理好两种正常的情况就差不多了,

笔试题36. LeetCode OJ (23)

合并K个排序链表,没错.我的思路是分别从 K 个链表的中找出最小的一个值,然后依次插入链表,最后遍历完所有链表就好了,也没想中的那么难呀,循环遍历的思路如下: (先说明一下,它是不合格的) 主要思路是: 1.首先从所有排序链表里找一个最小val节点作为头结点 2.依次循环在各个链表里面找到最小节点摘下来尾插,循环结束的条件是当链表的数目为0或者为1的时候结束(可以通过lists[i]==NULL来判断lists[i]代表的链表是否结束了),还编写了一个函数用来找最小元素下标的,每次返回的list

笔试题30. LeetCode OJ (17)

这个题目有意思,和生活接近,题目的意思一看就知道,应该是字符串的全排列吧.但是需要注意的是有几数字字符是没有对应的字符串的,比如'0'和'1',所以我们的输入字符串中若有他们,则将它们过滤掉.这个题我的思路是递归,因为这种类型的题目递归思路清晰明了,若要使用循环,则会形成n层循环,所以循环的思想应该被淘汰掉.我在做这个题的时候喜欢先把"多余"的东西先给它解决掉,比如'0'和'1'这两个数字,我先遍历一边digits数组,将'0'和'1'过滤掉,这样在后面的递归中可以少考虑一些东西,自认

笔试题74. LeetCode OJ (61)

    Rotate List    这个题的意思旋转链表,更具体点的意思右移链表,移出去的节点放到头部前面,结合着题目给出的例子还是很好理解的. 这个题的主要思路是:摘取从末尾到头的k个节点,然后将他们放到头部. 需要注意的是,上面说的k并不一定等于传入的k的值,因为这个k很可能比链表的长度还大.所以我主要思路是:遍历一遍链表,找到链表的长度n,然后k%=n(这时候k<n,我们更喜欢的是此时k=0),这样就可以找出实际需要移动的节点的个数,然后将链表的最后k个节点放到链表的前面就行了.大概方法