LeetCode 367. Valid Perfect Squarehtml
判断一个正数是不是彻底平方数,不可以使用sqrt函数。c++
这是一道简单题,可是却挺有思考价值的。本题有不少种解法,思路各异,能够都看看。算法
数学里有一个概念叫作等差数列,彻底平方数刚好是奇数等差数列之和。1+3+5+...+(2n-1)=(1+2n-1)n/2=n^2。既然有了这个,那就好办了,从小到大依次减去奇数,最后判断是否等于0便可。时间复杂度为 \(O(sqrt(n))\)。参考代码以下:函数
class Solution { public: bool isPerfectSquare(int num) { int x = 1; while (num > 0) { num -= x; x += 2; } return num == 0; } };
从1搜索到sqrt(num),时间复杂度为 \(O(sqrt(n))\)。参考代码以下:spa
class Solution { public: bool isPerfectSquare(int num) { for (int i = 1; i <= num / i; ++i) { if (i * i == num) return true; } return false; } };
其实就是搜索一个数,天然能够想到二分法。时间复杂度 \(O(lg(n))\)。参考代码以下:code
class Solution { public: bool isPerfectSquare(int num) { long left = 0, right = num; while (left <= right) { long mid = left + (right - left) / 2, t = mid * mid; if (t == num) return true; else if (t < num) left = mid + 1; else right = mid - 1; } return false; } };
万恶的算法,居然还有一个 \(O(1)\) 的解法,不过很难弄懂。参考连接:O(1) time c++ solution inspired by Q_rsqrt。想弄懂的还能够参考一下这个概念:Fast Inverse Square Root。htm
代码大概是这个样子的,学不来学不来:blog
class Solution { public: bool isPerfectSquare(int num) { if (num < 0) return false; int root = floorSqrt(num); return root * root == num; } int32_t floorSqrt(int32_t x) { double y=x; int64_t i=0x5fe6eb50c7b537a9; y = *(double*)&(i = i-(*(int64_t*)&y)/2); y = y * (3 - x * y * y) * 0.5; y = y * (3 - x * y * y) * 0.5; i = x * y + 1; return i - (i * i > x); } };
LeetCode All in One题解汇总(持续更新中...)ip
本文版权归做者AlvinZH和博客园全部,欢迎转载和商用,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文链接,不然保留追究法律责任的权利.leetcode