Leetcode日练笔记1 #704 Binary Search (Easy)

刚自学完 Codecademy 的数据结构,因为上面的随练比较少,加上对知识点的掌握和理解还不够,所以开始在 Leetcode 上根据 b站 Christinaaaya 的建议,按知识板块从易到难做题。

用的是 Leetcode 上 explore 版块,先从 binary search 入手。

背景一章,给的是 #704.

题目:

Given an array of integers nums which is sorted in ascending order, and an integer target, write a function to search target in nums. If target exists, then return its index. Otherwise, return -1.

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

 第一次写的是:

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        while nums is not None:
            mid = len(nums) // 2
            if nums[mid] == target:
                return mid
            if len(nums) != 1:
                if nums[mid] > target:
                    nums = nums[:mid]
                else:
                    nums = nums[mid+1:]
            else:
                return -1

test case 是

[-1,0,3,5,9,12]
9

结果 output 是 0 ,而 expected output 是 4 .

才意识我这么 truncate 会改掉原  index ,这不是题目要的。如果要保留原 index ,同时能不断缩小范围,就不能用 nums 储存缩小的信息。后来对比 solution ,才想起来,应该用 pointer 。于是改成这样:

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

用 left,right 框柱缩小范围的信息。run code 结果显示 accepted。submit 显示有误。

问题出在当 left 和 right 重合时,没有判断最后一个值是否是 target 就默认 -1 .导致错判。

while 的 condition 里补上 = 之后再 submit ,accepted 。但是 runtime 结果只处于 42.94% 。

于是打开位于前列的解法:

对比后,发现这个解法和我的不同之处在于:

1.合并了 return 这步输出

把判断和 target 值相不相等放在了 while 循环之外。

这个更快的解法的 while 的 condition 并不包含 = ,这意味着循环之外左标 left 和右标 right 合并了。合并之后剩最后一个值再判断是不是target。因此省去了循环里反复看中间值是不是target的这一步。

2.pivot的取值方式不同

取中值他的做法是以左标为锚点,然后加差值加一的一半。

我直接左标右标index值之和取一半。

有何不同?

用我的方法的话,当剩到最后左标和右标相邻时,pivot还是等于左标。

若左标小于或等于目标值,那左标永远不移动。这会造成左标index永远小于右标index,而走不出循环。所以我那种取中值方式不可取。

因此我第三次写成了:

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

可是runtime却是70.55%。 

明明是一样的解法,runtime结果还是不同。于是我谷歌了一下why leetcode Accepted Solutions Runtime Distribution diff every time:Loading...Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.https://leetcode.com/discuss/general-discussion/136683/different-run-time-with-same-code原来是大家都遇到了这个问题,算是leetcode的一个bug。

那就只把runtime result当做相对参考,以及学习其中更优解的思路。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值