Open azl397985856 opened 3 years ago
Problem Link
Ideas
if middle ** 2 <= x and if (middle + 1) ** 2 > x: return middle
Complexity: hash table and bucket
Code
class Solution:
def mySqrt(self, x: int) -> int:
if x == 0: return 0
left, right = 1, x
while left < right:
middle = (left + right) // 2
#print (middle)
if middle ** 2 <= x:
if (middle + 1) ** 2 > x:
return middle
left = middle
else:
right = middle
return left
#1, x , left = middle, right = middle, return left
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:
r = mid - 1
if mid ** 2 <= x:
ans = mid
l = mid + 1
return int(ans)
class Solution:
def mySqrt(self, x: int) -> int:
r = x + 1 # avoid dividing 0
while r*r > x:
r = int(r - (r * r - x) / (2 * r)) # newton's method
return r
Binary search,
class Solution {
public:
int mySqrt(int x) {
if (x < 2)
return x;
int lo = 2, hi = x / 2;
while (lo <= hi) {
long mid = lo + (hi - lo) / 2;
long num = mid * mid;
if (num == x)
return mid;
else if (num > x)
hi = mid - 1;
else
lo = mid + 1;
}
return lo - 1;
}
};
O(logx)
O(1)
二分搜索
def mySqrt(self, x: int) -> int:
if x==0 or x==1:
return x
l, r = 0, x
res=(l+r)//2
while not(res*res<=x and (res+1)*(res+1)>x):
if res*res>x:
r=res
else:
l=res
res=(l+r)//2
return res
一次摸奖99%
二分法
class Solution {
public int mySqrt(int x) {
int left = 0;
int right = x;
while(left < right){
int mid = left + (right - left) / 2; //向下取整
if(mid * mid >= x){
right = mid;
}else{
left = mid + 1;
}
}
return (long)left * left == x ? left : left -1
}
}
class Solution
{
public:
int mySqrt(int x)
{
if (x == 0) return 0;
int left{ 1 };
int right{ x };
while (left <= right) {
int mid = left + (right - left) / 2;
int x1 = x / mid;
if (x1 == mid) {
left = mid + 1;
} else if (x1 > mid) {
left = mid + 1;
} else if (x1 < mid) {
right = mid - 1;
}
}
return right;
}
};
搜索右侧插入位置的二分模板(右侧边界,即搜索的是最后一个满足 v ≤ ∟ x / v
的位置),+1的操作主要是为了避免发生死循环(一个补丁),因为 >>
等效于向下取整,例如 l = 0 , r = 1
时候 0 + 1 / 2
= 0 , l 仍是0,就会发生死循环。
var mySqrt = function(x) {
let l = 0;
let r = Math.ceil(x / 2); // 搜索区间的定界 这里定义为 x / 2 可以缩小一半初始搜索区间 不影响正确答案
let mid;
while(l < r) {
mid = ((r - l) >> 1) + l + 1; // + 1 补丁 避免死循环
if (mid <= Math.floor(x / mid)) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
};
时间复杂度: O(logn)
额外空间复杂度: O(1)
二分
, 双指针
class Solution(object):
def mySqrt(self, x):
"""
:type x: int
:rtype: int
"""
low, up = 0, x
while low**2 <= x:
mid = (low+up) // 2
if mid**2<=x and (mid+1)**2>x:
return mid
elif mid**2>x:
up = mid - 1
else:
low = mid + 1
使用二分法
class Solution:
def mySqrt(self, x: int) -> int:
leftValue = 0
rightValue = x
while(leftValue <= rightValue):
middleValue = (leftValue + rightValue) // 2
print(middleValue)
if(middleValue * middleValue > x):
rightValue = middleValue - 1
elif(middleValue * middleValue < x):
leftValue = middleValue + 1
else:
return middleValue
middleValue = (leftValue + rightValue) // 2
return middleValue
时间复杂度 :O(log N)
空间复杂度:O(1)
采用二分模板,找到中间值,如果mid相乘减去原来的数小于一个精度值,那么我们就认为是开平方的结果。
class Solution {
public int mySqrt(int x) {
double n = (double)x;
double l = 0,r = n;
while(l <= r){
double mid = (l+r)/2;
if(Math.abs(mid*mid-n) < 1e-6) return (int)mid;
if(mid*mid-n > 1e-6) r = mid-1e-6;
else l = mid+1e-6;
}
return (int)l;
}
}
时间复杂度:O(logn)
空间复杂度:O(1)
二分法。寻找最右边的满足条件的值。
class Solution {
public int mySqrt(int x) {
int l = 0, r = x;
int mid = 0;
int ans = -1;
while (l <= r) {
mid = l + (r - l) / 2;
if ((long) mid * mid <= x) { // convert to long to avoid overflow
ans = mid;
l = mid + 1;
}
else {
r = mid - 1;
}
}
return ans;
}
}
复杂度分析
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:
r = mid - 1
if mid ** 2 <= x:
ans = mid
l = mid + 1
return int(ans)
思路:核心使用二分,但是需要有几点注意,如果使用乘法作为二分条件时候,需要考虑是否越界的问题(也可以使用除法,x/mid与mid进行比较).
class Solution { public int mySqrt(int x) { if(x==0)return 0; int left = 1,right = 46340; while(left<=right){ int mid = (right -left)/2 + left; if(mid*mid==x){ return mid; }else if(mid*mid<x){ left = mid+1; }else{ right = mid -1; } } return right; } }
二分法,注意爆int的问题
class Solution {
public:
int mySqrt(int x) {
int l=0,r=x;
int ans=-1;
while(l<=r)
{
int mid=(l+r)>>1;
long long int p=(long long)mid*mid;
if(p==x)
return mid;
else if(p<x)
{
ans=mid;
l=mid+1;
}
else if(p>x)
r=mid-1;
}
return ans;
}
};
复杂度分析
class Solution:
def mySqrt(self, x: int) -> int:
left, right = 0, x
# find the last ele, that ele * ele <= x
while left + 1 < right:
mid = (left + right) // 2
if mid * mid == x:
return mid
elif mid * mid > x:
right = mid
else:
left = mid
if right * right <= x:
return right
return left
class Solution:
def mySqrt(self, x: int) -> int:
# 闭合区间 [l,r]
l = 0
r = x
while l<=r:
mi = (l+r) // 2
if mi*mi == x: return mi
elif mi*mi > x:
r = mi
else:
if (mi+1)*(mi+1) > x:
return mi
else:
l = mi + 1
return -1
二分
class Solution:
def mySqrt(self, x: int) -> int:
l, r = 0, x
res = 0
while l <= r:
mid = (l + r) // 2
if mid ** 2 <= x:
res = mid
l = mid + 1
else:
r = mid - 1
return res
时间:O(log x) 空间:O(1)
二分:寻找最右边的满足n^2 <= x 的值
class Solution(object):
def mySqrt(self, x):
"""
:type x: int
:rtype: int
"""
res, l, r = 0, 0 ,x
while l <= r:
mid = (l + r) // 2
if mid ** 2 == x:
res = mid
l = mid + 1
if mid ** 2 < x:
res = mid
l = mid + 1
if mid ** 2 > x:
r = mid - 1
return res
T: logx S: 1
思路
二分搜索
代码
class Solution {
public int mySqrt(int x) {
int left = 0,right = x;
if(x == 0 || x == 1){
return x;
}
while(left + 1 < right){
int mid = left + (right - left)/2;
if(mid >= x/mid){
if(mid == x/mid){
return mid;
}
right = mid;
}else{
left = mid;
}
}
return left;
}
}
复杂度
时间复杂度:O(logN)
空间复杂度:O(1)
class Solution:
def mySqrt(self, x: int) -> int:
left, right, ans = 0, x, 0
while left <= right:
mid = (left + right) // 2
if (mid * mid) <= x:
ans = mid
left = mid + 1
else:
right = mid - 1
return ans
二分搜索
class Solution:
def mySqrt(self, x: int) -> int:
left, right = 0, x-1
res = 0
if x == 0: return 0
if x == 1: return 1
while left <= right:
mid = left + (right-left)//2
if mid**2 < x: #it means that sqrt(x)>mid,start from mid+1,right
res = mid
left = mid + 1
elif mid**2 > x:
right = mid -1
elif mid**2 == x:
return mid
return res
Binary Search
class Solution:
def mySqrt(self, x: int) -> int:
if x <= 1: return x
left, right = 0,x
while(left < right):
mid = (left + right)//2
if mid * mid <= x:
left = mid + 1
else:
right = mid
return left-1
Space: O(1) Time: O(logx)
convert this problem to 'find the maximum value in [0...x-1] list where val^2 <= x' Using the "find_right_boundary" frame and pay attention to check boundary condition.
class Solution:
def mySqrt(self, x: int) -> int:
#binary search approach, finding the rightest answer where i^2 <= x
left = 0
right = x-1
while left <= right:
mid = int(left + (right - left)/2)
if mid * mid > x:
right = mid - 1
elif mid * mid == x:
left = mid + 1
elif mid * mid < x:
left = mid + 1
# boundary condition
if x <= 1:
return x
return right
直接调用现成的方法
``
class Solution {
/**
* 二分查找
* @param x
* @return
*/
public int mySqrt(int x) {
int l = 0, r = x/2 + 1, 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)
直接二分查找 Python 3 code
class Solution:
def mySqrt(self, x: int) -> int:
if x < 2:
return x
l, r = 2, x // 2
while l <= r:
mid = (l + r) // 2
if mid * mid == x:
return mid
elif mid * mid < x:
l = mid + 1
else:
r = mid - 1
return l - 1
TC: O(logn) SC: O(1)
class Solution:
def mySqrt(self, x: int) -> int:
if x <= 1:
return x
l = 0
r = x//2
while l<=r:
mid = (l+r)//2
if mid**2 == x:
return mid
elif mid**2 >x:
r = mid -1
elif mid**2 < x:
l = mid + 1
return r
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 }`
Plan:
binary search
time: O(logx)
space: O(1)
3
0 3
mid = 1
l = 2
mid = 2
r = 1
Tests:
2147395599 -> 46339
mid * mid overflow
8
l 3
r 2
m 2
class Solution {
public int mySqrt(int x) {
int l = 1, r = x; // l=0 won't work for 0 case
while (l <= r) {
int mid = l + (r - l) / 2;
if (x / mid == mid) {
return mid;
} else if (mid < x / mid) {
l = mid + 1;
} else {
r = mid - 1;
}
}
return r;
}
}
二分法
class Solution {
public int mySqrt(int x) {
if (x == 0 || x == 1) return x;
int left = 1, right = x;
while (left < right) {
// 特殊情况: x = Math.pow(2, 31); 如果left = 0, middle为负值
int middle = left + (right - left + 1) / 2;
// if判断跟向上取整还是向下取整没有关系
if ((long)middle * middle <= x) {
// 由于不判断等号,此时的middle有可能为解
left = middle;
} else {
right = middle - 1;
}
}
return left;
}
}
Binary Search
class Solution:
def mySqrt(self, x: int) -> int:
if x == 0:
return 0
l = 1
r = x
ans = 0
while l <= r:
mid = l + (r - l) // 2
if mid ** 2 > x:
r = mid - 1
if mid ** 2 <= x:
ans = mid
l = mid + 1
return ans
Time complexity: O(logn). Space complexity: O(1)
Binary search
class Solution:
def mySqrt(self, x: int) -> int:
left, right = 0, x
while left <= right:
mid = (left + right) // 2
if mid * mid > x:
right = mid -1
elif mid * mid < x:
left = mid + 1
else:
return mid
return right
时间复杂度:O(logn) 空间复杂度:O(1)
https://leetcode.com/problems/sqrtx/
while (start + 1 < end)
and int mid = start + (end - start)/2
class Solution {
public int mySqrt(int x) {
if(x == 1){
return 1;
}
int start = 2;
int end = x / 2; // sqt(x) < x/2
while(start + 1 < end){
int mid = start + (end - start) / 2;
long num = (long)mid * mid; // x <= 2^31 - 1, so x/2 * x/2 could be int overflow
if(num > x){
end = mid;
}else if(num < x){
start = mid;
}else{
return mid;
}
}
// looking for the biggest integer k where k * k < x, so check end before start
long num = (long)end * end;
if(num <= x){
return end;
}
return start;
}
}
https://leetcode.com/problems/sqrtx/
Hard
Medium
binary search
class Solution:
def mySqrt(self, x: int) -> int:
if x <2:
return x
left, right = 0, x
while left <= right:
mid = left + (right -left)//2
if mid** 2 > x:
right = mid -1
elif mid** 2 < x:
left = mid + 1
else:
return mid
return right
时间复杂度: O(logn) 空间复杂度:O(1)
二分法, 根号x 必定是 0-x之间, 二分法找最近(round down)
class Solution {
public int mySqrt(int x) {
long low = 0;
long high = x;
while (low + 1 < high) {
long mid = low + (high - low) / 2;
if (mid * mid == x) {
return (int)mid;
}
if (mid * mid > x) {
high = mid;
} else {
low = mid;
}
}
if (high * high <= x) {
return (int)high;
}
return (int)low;
}
}
思路:二分法
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)
利用二分法。
class Solution:
def mySqrt(self, x: int) -> int:
start,end = 0,x
while start<=end:
mid = (end+start)//2
if mid**2<=x:
start = mid+1
else:
end=mid-1
return end
复杂度分析
var mySqrt = function(x) {
let low = 0;
let high = Math.floor(x/2)+1;
let middle = 0;
while (low**2 < x && high**2 > x && (high-low)>1){
middle = Math.floor((low+high)/2);
if (middle**2 > x){
high = middle-1;
}else if (middle**2 === x){
return middle;
}else{
low = middle;
};
};
return high**2 <= x ? high : low;
};
【day37】69. x 的平方根
https://leetcode-cn.com/problems/sqrtx
二分法:注意一点:题中由于向下是取整,因此找的是满足 x^2<=8 的最大值,返回的是right
class Solution:
def mySqrt(self, x: int) -> int:
# 二分法
left = 0
right = x
while left <=right:
mid = left +(right - left)//2
if mid**2 > x:
right = mid -1
elif mid**2 < x:
left = mid+1
else:
return mid
return right
复杂度:
时间复杂度:O(log n)
空间复杂度:O(1)
class Solution {
public:
int mySqrt(int x) {
if(x==0) return 0;
if(x==1) return 1;
for(long int i=1;i <=x/2; i++){
if(i*i==x){
return i;
}
if(i*i<x && (i+1)*(i+1)>x){
return i;
}
}
return 0;
}
};
class Solution {
public:
int mySqrt(int x) {
if(x==1) return 1;
int min = 0;
int max = x;
while(max - min > 1){
int m = (max+min)/2;
if(x/m<m){
max = m;
}else{
min = m;
}
}
return min;
}
};
Time:O(n) Space:O(1)
class Solution:
def mySqrt(self, x: int) -> int:
start,end = 0,x
while start<=end:
mid = (end+start)//2
if mid**2<=x:
start = mid+1
else:
end=mid-1
return end
https://leetcode-cn.com/problems/sqrtx/
二分区间
class Solution:
def mySqrt(self, x: int) -> int:
# time logn
# space 1
# 二分区间
#
if x == 0: return 0
left, right = 1, x
while left < right:
mid = left + (right - left + 1) // 2
if mid * mid > x:
right = mid - 1
else:
left = mid
return left
二分法
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;
}
二分法
Java Code:
public 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;
}
}
复杂度分析
令 n 为数组长度。
/**
* @param {number} x
* @return {number}
*/
const mySqrt = function(x) {
if (x < 2) return x;
let start = 1;
let end = ~~(x / 2);
while (start <= end) {
const mid = start + ~~((end - start) / 2);
if (mid * mid <= x) {
start = mid + 1;
} else {
end = mid - 1;
}
}
return end;
};
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
二分搜索找到最右边的<=target的值
class Solution {
public int mySqrt(int x) {
if(x == 1){
return 1;
}
int l = 1;
int r = x/2;
while(l<=r){
int mid = l+(r-l)/2;
if((long) mid * mid == x){
return mid;
}
if((long) mid * mid < x){
l = mid+1;
}else{
r = mid-1;
}
}
return r;
}
}
class Solution {
public int mySqrt(int x) {
int res = 0;
int left = 0, right = 46340;
while (left <= right) {
int mid = (left + right) / 2;
long temp = mid * mid;
if (temp == x) {
return mid;
} else if (temp > x) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return right;
}
}
二分查找 注意都为闭区间[left, right]
class Solution {
public:
int mySqrt(int x) {
int left = 0;
int right = x;
int ans = -1;
while (left <= right) {
int mid = left + (right - left) / 2;
if ((long long)mid * mid <= x) {
ans = mid;
left = mid + 1;
} else {
right = mid - 1;
}
}
return ans;
}
};
//二分查找,查找区间[0, x]
int mySqrt(int x) {
int left = 0, right = x, res = 0;
while (left <= right) {
int mid = left + (right - left) / 2;
//由于结果向下取整,因此等于时的情况与小于时的合并
if ((long long)mid * mid <= x) {
res = mid;
left = mid + 1;
}
else {
right = mid - 1;
}
}
return res;
}
复杂度:
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;
}
}
时间复杂度:O(logn) 空间复杂度:O(1)
二分
class Solution {
public int mySqrt(int x) {
if(x==0) return 0;
if(x==1) return 1;
int l =0,r=x;
int mid;
while(l<=r){
mid = l + (r - l)/2;
if(x/mid==mid) return mid;
if(x/mid>mid) l = mid + 1;
if(x/mid<mid) r = mid - 1;
}
return l-1;
}
}
时间复杂度:O(logn) 空间复杂度:O(1)
69. x 的平方根
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/sqrtx
前置知识
题目描述
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4 输出: 2 示例 2:
输入: 8 输出: 2 说明: 8 的平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去