69.Sqrt(x)修改

This commit is contained in:
游由 2021-11-11 14:47:41 +08:00
parent 8a4ab3e507
commit 70fbfabb95
9 changed files with 191 additions and 112 deletions

View File

@ -18,12 +18,12 @@ var xorOperation = function (n, start) {
var mySqrt = function (x) {
const xHalf = 0.5 * x;
let i = new BigInt64Array(new Float64Array([x]).buffer)[0];
i = 0x5FE6EC85E7DE30DAn - (i >> 1n);
i = 0x1FF7A3BEA91D9B1Bn + (i >> 1n);
let f = new Float64Array(new BigInt64Array([i]).buffer)[0];
f = f * (1.5 - xHalf * f * f);
f = f * (1.5 - xHalf * f * f);
f = f * (1.5 - xHalf * f * f);
return Math.floor(1.0 / f);
f = f * 0.5 + xHalf / f;
f = f * 0.5 + xHalf / f;
f = f * 0.5 + xHalf / f;
return Math.floor(f);
};
/**

View File

@ -17,5 +17,22 @@ namespace my_leetcode
{
return new int[4] { nums.Length, 1, nums.Length + 1, 0 }[nums.Length & 3] ^ nums.Aggregate(0, (o, n) => o ^ n);
}
/// <summary>
/// 69.Sqrt(x)
/// </summary>
/// <param name="x">x</param>
/// <returns>平方根</returns>
public int MySqrt(int x)
{
double xHalf = 0.5 * x;
long i = BitConverter.DoubleToInt64Bits(x);
i = 0x1FF7A3BEA91D9B1B + (i >> 1);
double f = BitConverter.Int64BitsToDouble(i);
f = f * 0.5 + xHalf / f;
f = f * 0.5 + xHalf / f;
f = f * 0.5 + xHalf / f;
return (int)f;
}
}
}

View File

@ -39,11 +39,11 @@ int Solution::mySqrt(int x) {
};
double xHalf = 0.5 * x;
f = x;
i = 0x5FE6EC85E7DE30DALL - (i >> 1);
f = f * (1.5 - xHalf * f * f); // 牛顿迭代法,重复此句可提高精度
f = f * (1.5 - xHalf * f * f);
f = f * (1.5 - xHalf * f * f); // 三次迭代
return int(1.0 / f);
i = 0x1FF7A3BEA91D9B1B + (i >> 1);
f = f * 0.5 + xHalf / f; // 牛顿迭代法,重复此句可提高精度
f = f * 0.5 + xHalf / f;
f = f * 0.5 + xHalf / f; // 三次迭代
return f;
}

View File

@ -1,5 +1,19 @@
package main
import "math"
// 69.Sqrt(x)
func mySqrt(x int) int {
var xHalf = 0.5 * float64(x)
var i = math.Float64bits(float64(x))
i = 0x1FF7A3BEA91D9B1B + (i >> 1)
var f = math.Float64frombits(i)
f = f * 0.5 + xHalf / f
f = f * 0.5 + xHalf / f
f = f * 0.5 + xHalf / f
return int(f)
}
// 268.丢失的数字
func missingNumber(nums []int) int {
x := 0

View File

@ -15,12 +15,12 @@ public class Solution {
public int mySqrt(int x) {
double xHalf = 0.5 * x;
long i = Double.doubleToLongBits(x);
i = 0x5FE6EC85E7DE30DAL - (i >> 1);
i = 0x1FF7A3BEA91D9B1BL + (i >> 1);
double f = Double.longBitsToDouble(i);
f = f * (1.5 - xHalf * f * f);
f = f * (1.5 - xHalf * f * f);
f = f * (1.5 - xHalf * f * f);
return (int)(1.0 / f);
f = f * 0.5 + xHalf / f;
f = f * 0.5 + xHalf / f;
f = f * 0.5 + xHalf / f;
return (int) f;
}
public int deleteAndEarn(int[] nums) {

View File

@ -37,3 +37,19 @@ class Solution:
def missingNumber(self, nums: List[int]) -> int:
return [len(nums), 1, len(nums) + 1, 0][len(nums) & 3] ^ functools.reduce(lambda o, n: o ^ n, nums, 0)
def mySqrt(self, x: int) -> int:
"""
# 69.Sqrt(x)
:param x: x
:return: 平方根
"""
import struct
x_half = 0.5 * x
i = struct.unpack("Q", struct.pack("d", float(x)))[0]
i = 0x1FF7A3BEA91D9B1B + (i >> 1)
f = struct.unpack("d", struct.pack("Q", i))[0]
f = f * 0.5 + x_half / f
f = f * 0.5 + x_half / f
f = f * 0.5 + x_half / f
return int(f)

View File

@ -12,6 +12,7 @@ mod q0045;
mod q0046;
mod q0053;
mod q0055;
mod q0069;
mod q0070;
mod q0080;
mod q0081;

View File

@ -0,0 +1,128 @@
use crate::Solution;
impl Solution {
/// [69.Sqrt(x)](https://leetcode-cn.com/problems/sqrtx/)
///
/// 2021-11-11 11:00:34
///
/// 给你一个非负整数 `x` ,计算并返回 `x` 的 **算术平方根** 。
///
/// 由于返回类型是整数,结果只保留 **整数部分** ,小数部分将被 **舍去 。**
///
/// **注意:** 不允许使用任何内置指数函数和算符,例如 `pow(x, 0.5)` 或者 `x * 0.5` 。
///
/// * **示例 1**
/// + **输入:** x = 4
/// + **输出:** 2
/// * **示例 2**
/// + **输入:** x = 8
/// + **输出:** 2
/// + **解释:** 8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。
/// * **提示:**
/// * `0 <= x <= 2^31 - 1`
/// * Related Topics
/// + 数学
/// + 二分查找
///
/// * 👍 823
/// * 👎 0
/// # 方法1 内置函数
/// ```rust
/// pub fn my_sqrt(x: i32) -> i32 {
/// (x as f32).sqrt() as i32
/// }
/// ```
/// # 方法2 牛顿迭代法
/// f(x) = x^2 - c 的零点令x0=c,取f(x)在点(x0, f(x0))处切线的与x轴交点的坐标x1迭代上一步。
/// ## 源码
/// ```rust
/// pub fn my_sqrt(x: i32) -> i32 {
/// if x == 0 {
/// return 0;
/// }
/// let c = x as f64;
/// let mut x0 = x as f64;
/// loop {
/// let xi = 0.5 * (x0 + c / x0);
/// if (x0 - xi).abs() < 1e-7 {
/// break;
/// }
/// x0 = xi;
/// }
/// x0 as i32
/// }
/// ```
/// # 方法3 二分查找法
/// 实现见源码
/// ## 源码
/// ```rust
/// pub fn my_sqrt(x: i32) -> i32 {
/// let (mut l, mut r, mut ans) = (0, x, -1);
/// while l <= r {
/// let mid = l + (r - l) / 2;
/// if mid as i64 * mid as i64 <= x as i64 {
/// ans = mid;
/// l = mid + 1;
/// } else {
/// r = mid - 1;
/// }
/// }
/// ans
/// }
/// ```
/// # 方法4 袖珍计算器算法
/// 使用指数函数和对数函数替换平方根函数的方法
/// ## 源码
/// ```rust
/// pub fn my_sqrt(x: i32) -> i32 {
/// let ans = (0.5f64 * (x as f64).ln()).exp() as i32;
/// if (ans + 1) as i64 * (ans + 1) as i64 <= x as i64 {
/// ans + 1
/// } else {
/// ans
/// }
/// }
/// ```
/// # 方法5 卡马克快速平方根倒数
/// ```rust
/// pub fn my_sqrt(x: i32) -> i32 {
/// unsafe {
/// union X2f {
/// i: i64,
/// f: f64,
/// }
/// let x_half = 0.5f64 * x as f64;
/// let mut u = X2f { f: x as f64 };
/// u.i = 0x5FE6EC85E7DE30DA_i64 - (u.i >> 1);
/// u.f = u.f * (1.5f64 - x_half * u.f * u.f); // 牛顿迭代法
/// u.f = u.f * (1.5f64 - x_half * u.f * u.f);
/// u.f = u.f * (1.5f64 - x_half * u.f * u.f); // 三次迭代
/// return (1.0f64 / u.f) as i32;
/// }
/// }
/// ```
pub fn my_sqrt(x: i32) -> i32 {
let x_half = 0.5 * x as f64;
let mut i = (x as f64).to_bits();
i = 0x1FF7A3BEA91D9B1B + (i >> 1);
let mut f = f64::from_bits(i);
f = 0.5 * f + x_half / f;
f = 0.5 * f + x_half / f;
f = 0.5 * f + x_half / f;
f as i32
}
}
#[cfg(test)]
mod test {
use crate::Solution;
#[test]
fn test_q0069() {
let x = 2147395599;
let i = Solution::my_sqrt(x);
assert_eq!(i, 46339);
}
}

View File

@ -1932,95 +1932,6 @@ impl Solution {
ret
}
/// 69.x的平方根
///
/// [原题链接](https://leetcode-cn.com/problems/sqrtx/)
/// # 方法1 内置函数
/// ```rust
/// pub fn my_sqrt(x: i32) -> i32 {
/// (x as f32).sqrt() as i32
/// }
/// ```
/// # 方法2 牛顿迭代法
/// f(x) = x^2 - c 的零点令x0=c,取f(x)在点(x0, f(x0))处切线的与x轴交点的坐标x1迭代上一步。
/// ## 源码
/// ```rust
/// pub fn my_sqrt(x: i32) -> i32 {
/// if x == 0 {
/// return 0;
/// }
/// let c = x as f64;
/// let mut x0 = x as f64;
/// loop {
/// let xi = 0.5 * (x0 + c / x0);
/// if (x0 - xi).abs() < 1e-7 {
/// break;
/// }
/// x0 = xi;
/// }
/// x0 as i32
/// }
/// ```
/// # 方法3 二分查找法
/// 实现见源码
/// ## 源码
/// ```rust
/// pub fn my_sqrt(x: i32) -> i32 {
/// let (mut l, mut r, mut ans) = (0, x, -1);
/// while l <= r {
/// let mid = l + (r - l) / 2;
/// if mid as i64 * mid as i64 <= x as i64 {
/// ans = mid;
/// l = mid + 1;
/// } else {
/// r = mid - 1;
/// }
/// }
/// ans
/// }
/// ```
/// # 方法4 袖珍计算器算法
/// 使用指数函数和对数函数替换平方根函数的方法
/// ## 源码
/// ```rust
/// pub fn my_sqrt(x: i32) -> i32 {
/// let ans = (0.5f64 * (x as f64).ln()).exp() as i32;
/// if (ans + 1) as i64 * (ans + 1) as i64 <= x as i64 {
/// ans + 1
/// } else {
/// ans
/// }
/// }
/// ```
/// # 方法5 卡马克快速平方根倒数
/// ```rust
/// pub fn my_sqrt(x: i32) -> i32 {
/// unsafe {
/// union X2f {
/// i: i64,
/// f: f64,
/// }
/// let x_half = 0.5f64 * x as f64;
/// let mut u = X2f { f: x as f64 };
/// u.i = 0x5FE6EC85E7DE30DA_i64 - (u.i >> 1);
/// u.f = u.f * (1.5f64 - x_half * u.f * u.f); // 牛顿迭代法
/// u.f = u.f * (1.5f64 - x_half * u.f * u.f);
/// u.f = u.f * (1.5f64 - x_half * u.f * u.f); // 三次迭代
/// return (1.0f64 / u.f) as i32;
/// }
/// }
/// ```
pub fn my_sqrt(x: i32) -> i32 {
let x_half = 0.5f64 * x as f64;
let mut i = (x as f64).to_bits();
i = 0x5FE6EC85E7DE30DA_u64 - (i >> 1);
let mut f = f64::from_bits(i);
f = f * (1.5 - x_half * f * f);
f = f * (1.5 - x_half * f * f);
f = f * (1.5 - x_half * f * f);
(1.0f64 / f) as i32
}
/// 172.阶乘后的零
///
/// [原题链接](https://leetcode-cn.com/problems/factorial-trailing-zeroes/)
@ -3746,14 +3657,6 @@ mod tests {
assert_eq!(d, i32::MAX);
}
#[test]
fn test_my_sqrt() {
let x = 2147395599;
let i = Solution::my_sqrt(x);
//println!("{}", i);
assert_eq!(i, 46339);
}
#[test]
fn test_remove_stones() {
let stones = vec![vec![0, 0], vec![0, 1], vec![1, 0], vec![1, 2], vec![2, 1], vec![2, 2]];