[leetcode] Python(23)--二分查找(704)、x 的平方根(69)、猜数字大小(374)、搜索旋转排序数组(33)

从零开始的力扣(第二十三天)~

1.二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

示例 2:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

提示:
你可以假设 nums 中的所有元素是不重复的。
n 将在 [1, 10000]之间。
nums 的每个元素都将在 [-9999, 9999]之间。
—————————————————————————————————————————

使用两种方法实现二分查找,递归与非递归方法
class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        #递归
        n = len(nums)
        if n == 0:
            return -1
        
        mid = (n - 1) // 2
        if nums[mid] == target:
            return mid
        elif nums[mid] > target:
            ret = self.search(nums[0:mid], target)
            return ret if ret != -1 else -1
        else:
            ret = self.search(nums[mid+1:], target)
            return ret + mid + 1 if ret != -1 else -1
        #非递归
        n = len(nums)
        first = 0
        last = n - 1
        while first <= last:
            mid = (first + last) // 2
            if nums[mid] == target:
                return mid
            elif nums[mid] > target:
                last = mid - 1
            else:
                first = mid + 1
        return -1

递归方法:

非递归:

2.x 的平方根

实现 int sqrt(int x) 函数。

计算并返回 x 的平方根,其中 x 是非负整数。

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

示例 1:
输入: 4
输出: 2

示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842…, 由于返回类型是整数,小数部分将被舍去。
—————————————————————————————————————————

二分查找,找到当前数小于等于x,且当前数加一大于x的就是结果
class Solution(object):
    def mySqrt(self, x):
        """
        :type x: int
        :rtype: int
        """
        if x <= 1:
            return x
        first = 0
        last = x
        while first < last:
            mid = (first + last) // 2
            if mid ** 2 <= x and (mid + 1) ** 2 > x:
                return mid
            elif mid ** 2 > x:
                last = mid - 1
            else:
                first = mid + 1
        return first

牛顿迭代法
class Solution(object):
    def mySqrt(self, x):
        """
        :type x: int
        :rtype: int
        """
        if x <= 1:
            return x
        r = x
        while r > x / r:
            r = (r + x / r) // 2
        return int(r)

3.猜数字大小

我们正在玩一个猜数字游戏。 游戏规则如下:
我从 1 到 n 选择一个数字。 你需要猜我选择了哪个数字。
每次你猜错了,我会告诉你这个数字是大了还是小了。
你调用一个预先定义好的接口 guess(int num),它会返回 3 个可能的结果(-1,1 或 0):

-1 : 我的数字比较小
1 : 我的数字比较大
0 : 恭喜!你猜对了!

示例 :
输入: n = 10, pick = 6
输出: 6
—————————————————————————————————————————

照样二分法找数字,这里比较坑的是-1与1的状态,-1的意思是guess()函数内的数字比要猜的数字要大
# The guess API is already defined for you.
# @param num, your guess
# @return -1 if my number is lower, 1 if my number is higher, otherwise return 0
# def guess(num):

class Solution(object):
    def guessNumber(self, n):
        """
        :type n: int
        :rtype: int
        """
        first = 1
        last = n
        while first <= last:
            mid = (first + last) // 2
            if guess(mid) == 0:
                return mid
            elif guess(mid) == -1:
                last = mid - 1
            else:
                first = mid + 1

4.搜索旋转排序数组

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。

你可以假设数组中不存在重复的元素。

你的算法时间复杂度必须是 O(log n) 级别。

示例 1:
输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4

示例 2:
输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1
—————————————————————————————————————————

比较笨的方法,虽然使用二分查找,但是将所有左右情况找到,然后调用左右函数
class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        def half_search(nums, target, i, j, head):
            mid = int(0.5 * (j + i))

            if i > j:
                return -1
            if nums[mid] == target:
                return mid

            if (nums[mid] < target < head) or (head <= nums[mid] < target) or (nums[mid] >= head and target < head):
                return half_search(nums, target, mid + 1, j, head)
            else:
                return half_search(nums, target, i, mid-1, head)

        if not nums:
            return -1
        
        return half_search(nums, target, 0, len(nums) - 1, nums[0])

以上就是今日经验!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值