Leetcode日练笔记2 #69 #374 #33 sqrt() & Guess Number Higher or Lower & Search in Rotated Sorted Array

凡是要在一堆元素里寻找某个特定元素或其index的时候,都用binary search。

#69 求开根

Given a non-negative integer x, compute and return the square root of x.

Since the return type is an integer, the decimal digits are truncated, and only the integer part of the result is returned.

Note: You are not allowed to use any built-in exponent function or operator, such as pow(x, 0.5) or x ** 0.5.

也是从中间开始找开根值,一开始其平方会大过给定值。

再取半,当出现其平方小于给定值时,缩小取值范围再取半。缩小范围用左标右标框着。

直到最后剩相邻的两个值,输出左标。

之所以左标从0开始,是为了囊括x=0的情况。

一开始先看x是不是1,是为了排除x=1之后,left会无法挪动依旧为0,而输出0的情况。

(不过不太理解constraint在这里是?需要我干什么?)

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

runtime表现:

22ms的solution是:

class Solution:
    def mySqrt(self, x: int) -> int:
        return int(pow(x, 0.5))

但是不满足题目要求,用了内置function。就不算。

#374 猜大小

We are playing the Guess Game. The game is as follows:

I pick a number from 1 to n. You have to guess which number I picked.

Every time you guess wrong, I will tell you whether the number I picked is higher or lower than your guess.

You call a pre-defined API int guess(int num), which returns three possible results:

  • -1: Your guess is higher than the number I picked (i.e. num > pick).
  • 1: Your guess is lower than the number I picked (i.e. num < pick).
  • 0: your guess is equal to the number I picked (i.e. num == pick).

Return the number that I picked.

# The guess API is already defined for you.
# @param num, your guess
# @return -1 if num is higher than the picked number
#          1 if num is lower than the picked number
#          otherwise return 0
# def guess(num: int) -> int:


class Solution:
    def guessNumber(self, n: int) -> int:
        l, r, num = 0, n, n
        while guess(num) != 0:
            num = l + (r - l + 1)//2
            if guess(num) == 1:
                l = num
            else:
                r = num
        return num

runtime结果:

12ms的solution:

# 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: int) -> int:

class Solution:
    def guessNumber(self, n: int) -> int:
        
        # if n == 1:
        #     return 1
        start = 0
        end = n
        while True:
            mid = (start+end)//2
            val = guess(mid)
            if val  == -1:
                end = mid-1
                
            if val == 1:
                start = mid+1
            
            if val == 0:
                break
        return mid

不同之处在于:

1.判断condition更简单,而且不用总是算guess(num)的值,用变量val搞定,少跑几次。

2.中间值,直接左标右标之和。和之前找index不一样。只求值可以简单。

#33 Search in Rotated Sorted Array

There is an integer array nums sorted in ascending order (with distinct values).

Prior to being passed to your function, nums is possibly rotated at an unknown pivot index k (1 <= k < nums.length) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (0-indexed). For example, [0,1,2,4,5,6,7] might be rotated at pivot index 3 and become [4,5,6,7,0,1,2].

Given the array nums after the possible rotation and an integer target, return the index of target if it is in nums, or -1 if it is not in nums.

You must write an algorithm with O(log n) runtime complexity.

最后这句话好像用二分法的cue

以及不太懂这个constraint是需要我干什么?

解法思路:

不能用brute force的话,就只能先把被rotated的array给sorted回正常的ascending状态。并且保留原array的index信息。

然后找到了enumerate()

 可以把list里的element都过一遍,并记录下其index,以list of tuple的方式存起来。

所以存好原index信息后,就直接在sorted(nums)的基础上找target,找到就到回找对应的index,找不到就输出-1。

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        sorted_num = sorted(enumerate(nums), key=lambda i: i[1])
        new = sorted(nums)
        l, r = 0, len(new)-1
        while r > l:
            mid = l + (r - l + 1)//2
            if new[mid] > target:
                r = mid - 1
            else:
                l = mid
                
        if new[l] == target:
            for idx, val in sorted_num:
                if val == target:
                    return idx
        else:
            return -1

runtime结果:

73.04%

20ms的solution:

这个方法优点在于:

1.不需要生成新的list of tuple,比我节省了保存原index这一步。直接不改动原来的list来寻找目标值。

2.靠判断中间值与头或尾值的大小,看哪一半是升序的。有两种可能,一种右半升序,另种左半升序。左伴升序的情况下,如果目标值比中值小,比头值大,则目标值在左半边。反之在右半边。每一次取新的中值,都要比较中值与头值或尾值(任选一)的大小,以确定是左半还是右半升序。以此决定目标值在哪一半,扔掉哪一半数值。走出循环的条件是右标在左标左边,最后一步是右标挪至左标的左边。所以是相等于剩下左标对应的一个值,看这个值与目标值是否相等。等的话输出左标的index,不等则输出-1。

我原本的思路有点僵化,没有想过不sort也可以靠限制条件扔掉一半值。后来看参考solution也确实比较复杂。还是积累不够,无法想出这个办法。所以还得坚持练。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值