【力扣】Python分类刷题(二分查找专题)704,35,69,367,441

【力扣】Python分类刷题(二分查找专题)704,35,69,367,441,第1张

leetcode刷题,持续更新。python实现二分法

题目:704,35,69,367,441,33,34,153,162,4……

目录

704.二分查找

题目要求

题解

35.搜索插入位置

题目要求

题解

69.x的平方根

题目要求

题解

367.有效的完全平方数

题目要求

题解

441.排列硬币

题目要求

题解



704.二分查找 题目要求

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法

来源:力扣(LeetCode)
链接:力扣

题解

思路:典型二分查找

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        n=len(nums)
        if n==0:
            return -1
        left,right=0,n-1
        while left<=right:
            mid=(left+right)//2
            if nums[mid]>target:
                right=mid-1
            elif nums[mid]
35.搜索插入位置 题目要求

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。

来源:力扣(LeetCode)
链接:力扣

题解

方法一:

思路:因为left和right已经发生的交叉,left>right,所以返回的应该是left。

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        n = len(nums)
        left, right = 0, n-1
        while left <= right:
            mid = (left + right) // 2
            if nums[mid] < target:
                left = mid + 1
            elif nums[mid] > target:
                right = mid -1
            else:
                return mid
        return left

Java

class Solution {
    public int searchInsert(int[] nums, int target) {
        int left = 0;
        int right = nums.length -1;
        int mid = 0;
        while (left<=right){
            mid=(left+right)/2;
            if (nums[mid]target){
                right=mid-1;
            }
            else{
                return mid;
            }
        }
        return left;
    }
}

方法二:

思路:Python可以直接用bisect模块。

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        return bisect.bisect_left(nums,target)
69.x的平方根 题目要求

给你一个非负整数 x ,计算并返回 x 的 算术平方根 。

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。

来源:力扣(LeetCode)

链接:力扣

题解

方法一:暴力解决,从头开始算,直到找到

1.某个数的平方恰好=x,输出该数;2.某个数的平方x,输出该数。

但是,该方法时间超限。

class Solution:
    def mySqrt(self, x: int) -> int:
        if x==0 or x==1:
            return x
        else:
            for cur in range(x):
                if cur**2x:
                    return cur
                elif cur**2==x:
                    return cur

方法二:直接用库函数。

import math
class Solution:
    def mySqrt(self, x: int) -> int:
        return int(math.sqrt(x)) 

方法三:牛顿法

牛顿法原理:若想求2的平方根,列公式f(x)=x^2-2。当f(x)=0时,x=根号2。

在f(x)上随便取一点,以(2,2)为例,在该点做f(x)的切线,列出切线方程y=4x-6,求该切线方程在y=0时候的x值,x=1.5,将所求x值带回f(x)=0.25,此时这点坐标为(切线方程和x轴交点,对应的f(x)值)=(1.5,0.25)。

此时对这个点做上述 *** 作:求切线方程y=4x-5.75,切向方程与x轴交点x=1.4375。

可以发现切线方程与x轴的交点从x=1.5到x=1.4375,如果继续迭代,x会不断逼近根号二的真值1.4142……,如果最开始的初始值选择别的值,也不会耽误计算,影响的只是迭代次数。

参考链接(里面有图):如何手工开根号?(简述Newton-Raphson 法) - 知乎

数学部分讲完了,接下来是总结规律:

class Solution:
    def mySqrt(self, x: int) -> int:
        t=x
        while t*t>x:
            t=(t+x/t)//2
        return int(t)

方法四:二分法

class Solution:
    def mySqrt(self, x: int) -> int:
        left,right=0,x+1
        while left<=right:
            mid=(left+right)//2
            if mid**2>x:
                right=mid-1
            elif mid**2

牛顿法思路来源负雪明烛,参考链接:【LeetCode】69. Sqrt(x) 解题报告(Python & C++)_负雪明烛的博客-CSDN博客

367.有效的完全平方数 题目要求

给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false 。

进阶:不要 使用任何内置的库函数,如  sqrt 。

来源:力扣(LeetCode)
链接:力扣

题解

方法一:二分法

class Solution:
    def isPerfectSquare(self, num: int) -> bool:
        left,right=0,num+1
        while left<=right:
            mid=(left+right)//2
            if mid**2>num:
                right=mid-1
            elif mid**2

方法二:利用完全平方数的性质(是从1开始若干连续奇数的和)

class Solution:
    def isPerfectSquare(self, num: int) -> bool:
        i=1
        while num>0:
            num-=i
            i+=2
        return num==0

方法三:牛顿法

class Solution:
    def isPerfectSquare(self, num: int) -> bool:
        t=num
        while t**2>num:
            t=(t+num/t)//2
        return t**2==num

方法二(利用完全平方性质)、方法三(牛顿法)思路来源负雪明烛

参考链接:【LeetCode】367. Valid Perfect Square 解题报告(Java & Python)_负雪明烛的博客-CSDN博客

441.排列硬币 题目要求

你总共有 n 枚硬币,并计划将它们按阶梯状排列。对于一个由 k 行组成的阶梯,其第 i 行必须正好有 i 枚硬币。阶梯的最后一行 可能 是不完整的。

给你一个数字 n ,计算并返回可形成 完整阶梯行 的总行数。

来源:力扣(LeetCode)
链接:力扣

题解

方法一:暴力尝试,判断是否正好排布,如果正好就返回行数;如果不正好就返回行数-1。

class Solution:
    def arrangeCoins(self, n: int) -> int:
        row=0
        while n>0:
            row+=1
            n-=row
        if n==0:
            return row
        else:
            return row-1

方法二:等差数列前n项和+二分法

#等差数列求和公式
sn=a1*n+n*(n-1)*d/2   # a1:第一项; d:公差
sn=(a1+an)*n/2        # an:第n项
class Solution:
    def arrangeCoins(self, n: int) -> int:
        left,right=0,n+1
        while left<=right:
            mid=(left+right)//2  
            sn=mid+mid*(mid-1)/2  # 等差数列求和公式,第一项a1=1,d=1,所以省略了
                                  # 两个求和公式,用哪个都行
            if sn>n:
                right=mid-1
            elif sn

方法三:等差数列前n项和,反向求解行数,并向下取整

sn=(a1+an)*n/2
2*sn=(1+n)*n
n**2+n+1/4=2*sn+1/4        # 中学数学,构成完全平方项
(n+1)**2=2*sn+1/4
n=math.sqrt(2*sn+1/4)-1/2  # 此处的sn是题目要求的目标值n
import math
class Solution:
    def arrangeCoins(self, n: int) -> int:
        return int(math.sqrt(2*n+1/4)-1/2)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/870639.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)