Open azl397985856 opened 2 years ago
二分,找所有满足 ans ^ 2 <= 8 的最大值,也就是找最右边的满足条件的值。
def fun(x):
l=0
r=x
while(l<=r):
mid=(l+r)//2
if mid**2 >x:
r=mid-1
elif mid**2 <=x:
l=mid+1
ans=mid
return int(ans)
x=24
print(fun(x))
思路:
二分查找
复杂度分析:
代码(C++):
class Solution {
public:
int mySqrt(int x) {
int l = 0, r = x;
while (l <= r) {
long mid = l + (r - l)/2;
if ((mid * mid <= x) && ((mid + 1)*(mid + 1) > x))
return int(mid);
else if (mid * mid > x)
r = mid - 1;
else
l = mid + 1;
}
return l;
}
};
思路:使用二分法
class Solution {
public int mySqrt(int x) {
if(x==0||x==1)return x;
int l = 0,r = x;
int ans = -1;
while(l<=r){
int mid = l+((r-l)>>1);
if(mid>x/mid){
r = mid-1;
}else {
l = mid+1;
ans = mid;
}
}
return ans;
}
}
二分法求解
/**
* @param {number} x
* @return {number}
*/
var mySqrt = function(x) {
if(x <= 1){
return x
}
let i = Math.ceil(x/2)
while(i > 0){
if(i*i <= x) {
return i
}
let j = Math.ceil(i / 2);
if(j*j > x){
i = j
}else {
i--
}
}
};
空间复杂度 O(1) 时间复杂度 O(logn)
class Solution:
def mySqrt(self, x: int) -> int:
if x == 0 or x == 1:
return x
l, r = 0, x//2
while l<=r:
mid = l + (r-l)//2
if mid**2 == x:
return mid
if mid**2 < x:
l = mid+1
if mid**2 > x:
r = mid-1
return r
class Solution:
def mySqrt(self, x: int) -> int:
ans, l, r = 0, 0, x
while l <= r:
mid = (l + r) // 2
if mid**2 <= x:
ans = mid
l = mid + 1
else:
r = mid - 1
return ans
Time complexity O(log x) Space complexity O(1)
class Solution:
def mySqrt(self, x: int) -> int:
l, r = 0, x
while l <= r:
mid = (l + r) // 2
if mid ** 2 == x:
return mid
elif mid ** 2 < x:
l = mid + 1
elif mid ** 2 > x:
r = mid - 1
return r
class Solution {
public int mySqrt(int x) {
int l = 0, r = x, ans = -1;
while (l <= r) {
int mid = l + (r - l) / 2;
if ((long) mid * mid <= x) {
ans = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
return ans;
}
}
牛顿迭代法
class Solution {
public:
int mySqrt(int x) {
//牛顿迭代
if(x == 0){
return 0;
}
double x0 = x;
double c = x;
while(true){
//牛顿迭代法迭代
double xi = 0.5*(c/x0+x0);
if(x0-xi<1e-7){
break;
}
x0 = xi;
}
return x0;
}
};
复杂度分析
时间复杂度:O(logn)
空间复杂度:O(1)
二分法,找到第一个平方后大于target的数,答案是这个数-1。
class Solution: def mySqrt(self, x: int) -> int: if x < 2: return x
l, r = 0, x
while l < r:
mid = (l+r)//2
if mid*mid > x:
r = mid
else:
l = mid + 1
return r-1
TC: O(logx) SC: O(1)
class Solution: def mySqrt(self, x: int) -> int:
l = 0
r = x
while r >= l:
mid = l + (r-l)//2
if mid*mid>x:
r = mid -1
elif mid*mid<x:
l = mid + 1
else:
return mid
return r
二分
var mySqrt = function (x) {
let left = 0
let right = x
while (left <= right) {
let mid = left + ((right - left) >> 1)
if (mid * mid <= x) {
left = mid + 1
} else {
right = mid - 1
}
}
return right
};
时间复杂度:O(logn)
空间复杂度:O(1)
code:
public int mySqrt2(int x) {
long res = x;
while (res * res > x) {
res = (res + x / res) / 2;
}
return (int) res;
}
class Solution:
def mySqrt(self, x: int) -> int:
if x == 0:
return 0
ans = int(math.exp(0.5 * math.log(x)))
return ans + 1 if (ans + 1) ** 2 <= x else ans
class Solution {
public int mySqrt(int x) {
if (x == 0) {
return 0;
}
int ans = (int) Math.exp(0.5 * Math.log(x));
return (long) (ans + 1) * (ans + 1) <= x ? ans + 1 : ans;
}
}
复杂度分析
令 n 为数组长度。
数学题,用的牛顿迭代。
CPP
class Solution {
public:
int mySqrt(int x) {
long long c = x;
while (c * c > x)
c = (c + x / c) / 2;
return (int)c;
}
};
复杂度分析
难度简单
给你一个非负整数 x
,计算并返回 x
的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5)
或者 x ** 0.5
。
示例 1:
输入:x = 4
输出:2
示例 2:
输入:x = 8
输出:2
解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。
提示:
0 <= x <= 231 - 1
class Solution
{
public:
int num;
int mySqrt(int x)
{
if(x <0) throw "Negative number doesn't have square root.";
long l = 0, r = x;
long mid = l + (r - l) / 4;
long mid_square = 0;
while (l <= r)
{
mid_square = mid * mid;
if (mid_square == x)
return mid;
else if (mid_square < x)
{
if ((mid + 1) * (mid + 1) > x)
return mid;
else
l = mid + 1;
}
else if (mid_square > x)
{
r = mid - 1;
}
mid = l + (r - l) / 4;
}
return -1;//Not found.
}
};
Time complexity:$O(n)$
Space complexity: $O(1)$
class Solution(object): def mySqrt(self, x): """ :type x: int :rtype: int """ l=0 r=x while l<=r: mid=l+(r-l)/2 if midmid ==x or (midmid<x and (mid+1)(mid+1)>x): return mid elif midmid>x: r=mid-1 else: l=mid+1
class Solution {
public:
int mySqrt(int x) {
if (x ==0) return 0;
if (x < 4) return 1;
int left = 1;
int right = x / 2;
while(left <= right){
int mid = left + (right - left) / 2;
if ((long long)mid * mid < x){
left = mid+1;
} else if ((long long)mid * mid > x) {
right = mid -1;
} else {
return mid;
}
}
return right;
}
};
class Solution(object): def mySqrt(self, x): """ :type x: int :rtype: int """ l = 1 r = x ans = 0 while l<=r:
mid = (l+r) // 2
if mid**2 > x :
r = mid-1
if mid **2 <= x:
ans = mid
l = mid+1
return int(ans)
时间复杂度:O(logn) 空间复杂度:O(1)
var mySqrt = function(x) {
let l = 0, r = x, res = -1
while(l <= r) {
let mid = parseInt((l + r) / 2)
if (mid * mid <= x) {
res = mid
l = mid + 1
} else {
r = mid - 1
}
}
return res
};
C++ Code:
class Solution {
public:
int mySqrt(int x) {
long start = 0, end = x;
long mid = 0;
while (start <= end) {
mid = start + (end - start) / 2;
if (mid * mid == x) {
return mid;
} else if (mid * mid > x) {
end = mid - 1;
} else if (mid * mid < x) {
start = mid + 1;
}
}
if (end > 0 && end * end - x < start * start - x) {
return end;
}
return start;
}
};
复杂度分析
class Solution:
def mySqrt(self, x: int) -> int:
if x == 0:
return 0
ans = int(math.exp(0.5 * math.log(x)))
return ans + 1 if (ans + 1) ** 2 <= x else ans
思路 二分法
class Solution { public: int mySqrt(int x) { int l = 1, r = x, mid; while(l <= r){ mid = l + (r-l)/2; if(x/mid > mid) l = mid + 1; else if (x/mid < mid) r = mid - 1; else return mid; } return r; } };
时间复杂度:O(log_x) 空间复杂度:O(1)
牛顿法
int x0 = s / 2;
if ( x0 != 0 ){
int x1 = ( x0 + s / x0 ) / 2;
while ( x1 < x0 ){
x0 = x1;
x1 = ( x0 + s / x0 ) / 2;
}
return x0;
}else{
return s;
}
二分法
class Solution {
public int mySqrt(int x) {
int l = 0, r = x, ans = -1;
while (l <= r) {
int mid = l + (r - l) / 2;
if ((long) mid * mid <= x) {
ans = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
return ans;
}
}
O(logN) O(1)
// 1-17 cpp
class Solution {
public:
int mySqrt(int x) {
if (x == 0) return 0;
if (x == 1) return 1;
int min = 0;
int max = x;
while (max - min > 1) {
int m = (max + min)/2;
if (x / m == m) return m;
if (x / m < m) max = m;
else min = m;
}
return min;
}
};
二分法
const mySqrt = x => {
let left = 1, right = x
let ans
while(left <= right) {
const mid = (left + right) >>> 1
if (mid * mid === x) { return mid }
if (mid * mid < x) {
ans = mid
left++
} else {
right--
}
}
return ans
}
正常思路,i 从1累加,直到 i * i 等于 x ,返回 i; 大于 x ,返回 i - 1;小于 x ,i++
class Solution {
public int mySqrt(int x) {
// 正常思路:从1开始一直累加计算乘积,如果等于 x,找到了;如果小于,继续累加1;如果大于,则超了,返回上一个值
if (x == 0) return 0;
int i = 1;
while (i <= x) {
int multi = i * i;
if (multi > x || multi < 0) break;
else if (multi < x) i++;
else return i;
}
return i - 1;
}
}
难度简单864
给你一个非负整数 x
,计算并返回 x
的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5)
或者 x ** 0.5
。
方法1:二分查找
class Solution:
def mySqrt(self, x: int) -> int:
l = 0
r = x
while l <= r:
mid = l + ((r - l) >> 1)
val = mid * mid
if val < x:
l = mid + 1
elif val > x:
r = mid - 1
else:
return mid
# 最终退出时,l位于刚好大于目标值的位置上,r位于刚好小于目标值的位置上
return r
方法2:牛顿迭代法
class Solution:
def mySqrt(self, x: int) -> int:
if x == 0:
return 0
# 牛顿迭代法
x_old = x
while 1:
x_new = (x_old + x / x_old) / 2 # 根据梯度更新
if abs(x_old - x_new) < 1e-7:
break
x_old = x_new
# 最终停下的点位于真实值的右侧
return int(x_new)
class Solution {
public:
int mySqrt(int x) {
int l = 0, r = x;
while(l <= r){
int mid = l + ((r - l) >> 1);
long long val = (long long)mid * mid;
if(val < x){
l = mid + 1;
}
else if(val > x){
r = mid - 1;
}
else{
return mid;
}
}
return r;
}
};
二分法,从1累加具有单调递增性质,考虑使用二分法
class Solution {
public int mySqrt(int x) {
// 思路2: 二分法,从1累加具有单调递增性质,考虑使用二分法
if (x < 2) return x;
int left = 1, right = x;
while (left + 1 < right) {
int mid = left + ((right - left) >> 1);
if (mid >= x / mid) {
right = mid;
} else {
left = mid;
}
}
return right > x / right ? left : right;
}
}
class Solution { public int mySqrt(int x) { int l = 0, r = x , ans = -1; while(l <= r){ // int mid = (l + x) /2; int mid = l + (r - l) / 2; if((long)mid * mid <= x){ ans = mid; l = mid + 1; }else { r = mid - 1; } } return ans; } }
/**
* @param {number} x
* @return {number}
*/
var mySqrt = function (x){
let l = 0;
let r = x
while( l < r ){
let mid = l+r+1 >> 1
if(mid <= x / mid){
l = mid
}else{
r = mid - 1
}
}
return l
}
LeetCode题目连接: 69. Sqrt(x)https://leetcode-cn.com/problems/sqrtx/
二分法,得到二分结果后再判断其平方是否大于目标值 x。
class Solution:
def mySqrt(self, x: int) -> int:
left, right = 0, x
while left < right:
mid = (left+right)//2
if mid*mid == x:
return mid
elif mid*mid < x:
left = mid+1
else:
right = mid
if left*left > x:
return left-1
else:
return left
复杂度分析
基本的二分法,和第27天的基本是一样的。 换个变量就好了
public static int mySqrt(int x) {
if(x==1) return 1;
int begin=0;
int end=46340;
while(begin<=end){
int mid=begin+(end-begin)/2;
if(mid*mid>x){
end=mid-1;
}else if(mid*mid<x){
begin=mid+1;
}else{
return mid;
}
}
return end;
}
class Solution {
public int mySqrt(int x) {
// 利用二分法
int left = 0, right = x, ans = -1;
while(left <= right) {
int mid = left + (right - left) / 2;
if((long)mid * mid <= x) {
ans = mid;
left = mid + 1;
} else {
right = mid - 1;
}
}
return ans;
}
}
二分法查找
class Solution
{
public:
int mySqrt(int x)
{
int l = 1, r = x, mid;
while (l <= r)
{
mid = l + (r - l) / 2;
if (x / mid > mid)
l = mid + 1;
else if (x / mid < mid)
r = mid - 1;
else
return mid;
}
return r;
}
};
二分
class Solution {
public int mySqrt(int x) {
if (x <= 1) {
return x;
}
int l = 1, r= x / 2;
while (l <= r) {
int mid = (l + r) >>> 1;
if ((long)mid * mid == x) {
return mid;
}
if ((long)mid * mid > x) {
r = mid - 1;
} else {
l = mid + 1;
}
}
return r;
}
}
二分
class Solution {
public int mySqrt(int x) {
if(x == 0)
return 0;
if(x == 1)
return 1;
int left = 1;
int right = x / 2;
while(left < right){
int mid = left + (right - left + 1) / 2;
if(mid > x / mid){
right = mid - 1;
}else{
left = mid ;
}
}
return left;
}
}
时间复杂度O(logN) 空间复杂度O(1)
排除法
class Solution {
public int mySqrt(int x) {
if (x == 0) {
return 0;
}
if (x == 1) {
return 1;
}
int l = 0;
int r = x / 2;
while (l < r) {
int mid = l + (r - l + 1) / 2;
if (mid > x / mid) {
r = mid - 1;
} else {
l = mid;
}
}
return l;
}
}
时间复杂度:O(log2n) 空间复杂度:O(n)
二分法搜索,找到最大的res,使得res * res <= x。
var mySqrt = function(x) {
let left = 0, right = x;
let res = 0;
while(left <= right){
let mid = (left + right) >>> 1;
if(mid * mid <= x) res = mid;
if(mid * mid === x) return res;
else if(mid * mid < x) left = mid + 1;
else right = mid - 1;
};
return res;
};
复杂度分析
class Solution {
public:
int mySqrt(int x) {
if(x==1)return 1;
long target =x;
long low = 0;
long mid = target/2;
long high= target;
while ((mid*mid!=target)&&!(mid*mid<x&&(mid+1)*(mid+1)>target)){
if(mid*mid>x){
high = mid-1;
}else{
low = mid+1;
}
mid = (low+high)/2;
}
return mid;
}
};
JavaScript Code:
var mySqrt = function (x) {
let l = 0,
r = x,
ans = -1;
while (l <= r) {
const mid = Math.floor((l+r)/2)
if (mid * mid <= x) {
ans = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
return ans;
};
复杂度分析
令 n 为数组长度。
class Solution {
public:
int mySqrt(int x) {
int left = 0, right = x;
int ret;
while(left<=right)
{
int mid = (right-left)/2 + left;
if((long long)mid*mid>x)
right = mid-1;
else if((long long)mid*mid<x)
{
ret = mid;
left = mid+1;
}
else
return mid;
}
return ret;
}
};
二分法,无限向右逼近
/**
* @param {number} x
* @return {number}
*/
var mySqrt = function(x) {
if (x === 0 ) return 0;
if (x < 4) return 1;
let left = 0;
let right = x;
let middle;
let ans
while (left <= right) {
middle = Math.floor(left + (right - left)/2);
if (middle * middle <= x) {
ans = middle
left = middle + 1;
} else {
right = middle - 1;
}
}
return ans;
};
时间log(x),空间O(1)
var mySqrt = function(x) {
let left = 0; right = x, res = 0;
while(left <= right) {
let mid = (left + right) >>> 1;
if(mid*mid < x) {
left = mid + 1
} else if(mid*mid > x) {
right = mid - 1;
} else {
return mid
}
}
return right;
};
x的平方根
class Solution {
public int mySqrt(int x) {
int left=0;
int right=x;
while(left<=right)
{
int mid=(left+right)/2;
if(Math.pow(mid,2)<=x)
{left=mid+1;}
else if(Math.pow(mid,2)>x)
{right=mid-1;}
}
return right;
}
}
class Solution:
def mySqrt(self, x: int) -> int:
left = 0
right = x
while left < right:
mid = (left + right + 1 ) //2
if mid <= x / mid:
left = mid
else:
right = mid - 1
return left
小于右边界的最大值
class Solution {
public int mySqrt(int x) {
if(x==1)
return 1;
int left = 0, right = 46340;
while(left <= right) {
int mid = left + (right - left) / 2;
if(mid*mid == x)
return mid;
if(mid * mid < x) {
left = mid+1;
} else {
right = mid - 1;
}
}
return right;
}
}
O(lgN)
var mySqrt = function(x) { let left=0 let right=x while(left<=right){ let mid=left+((right-left)>>1) if(mid*mid<=x){ left=mid+1 }else{ right=mid-1 } } return right };
69. x 的平方根
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/sqrtx
前置知识
题目描述
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4 输出: 2 示例 2:
输入: 8 输出: 2 说明: 8 的平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去