最近发现自己的编程能力越来越下降,论文看的多,却太久没搞代码,都快忘光了,有点纸上谈兵的感觉,感觉要加强代码能力。因此,本人决定在每日的闲暇之余,要坚持每日至少做1题的习惯,认清自己是小白,记录解题过程,努力提升自身代码能力。
刷题网站:Leetcode
难度: 简单
语言: Python
计划:从简单——>到中等——>再到难。
一、704数组的二分查找
1.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
- 编辑栏:
class Solution:
def search(self,nums:List[int],target:int) -> int:
return -1
1.2 思考
第一次看到这个答题页面,首先观察了一下大概的流程和内容。想了一下,左边题目,右边解答,选择语言Python3
会自动出已有的编辑栏,应该是在此基础上进行编辑,下面有个执行代码
按钮和提交
按钮,所以先写出代码,然后执行代码判断是否正确,最后提交。
本题是给定的一个数组,而且是升序的,所以不用考虑输入随意的数组,它们的顺序也不是乱的,这样其实挺好找的。直接从左到右或从右到左进行遍历比较就行了(数组长度较短的情况下!)。
1.3 解题过程
首先,定义了类和方法,肯定要调用,代码加一个调用
class Solution:
def search(self,nums:List[int],target:int) -> int:
return -1
print(Solution().search([-1,0,3,5,9,12],9))
其次,就是方法里面的查找下标算法。想法是加一个for
循环,让数组从第一位开始与target
进行比较,相等就输出i
的值,也就是下标值,且跳出循环,不相等就继续比,直至最后一位后返回-1
,代码如下
class Solution:
def search(self,nums: List[int],target: int) -> int:
for i in range(len(nums)):
if target == nums[i]:
return i
break
elif i == len(nums)-1:
return -1
print(Solution().search([-1,0,3,5,9,12],9))
最后,执行代码通过,提交显示如下
只击败了7.99%的用户,肯定是我这个遍历方法不行啊,显示是数组较短,若长的话肯定不行,才反映过来这题目是要二分查找,那我这还没用到二分查找,然后点开了题解,理解了一下什么叫二分查找。
二分查找描述:给定一个有序数组,先比较中间值(下标为中间值)与target的值大小,若相等则输出下标值,若target小于(大于)中间值,则再比较左(右)区间中间值,以此类推。每次比较的范围缩小一半,若最终没有找到,则返回-1。
因此,进一步改进代码
class Solution:
def search(self,nums: List[int],target: int) -> int:
i = 0
j = len(nums) - 1
while i<=j:
mid = (j - i) // 2 + i
if target == nums[mid]:
return mid
elif target > nums[mid]:
i = mid + 1
else:
j = mid - 1
return -1
print(Solution().search([-1,0,3,5,9,12],2))
再一看已经击败了93.97%的用户,这个时间至少实现了进一步优化。
1.4 总结
特别注意,由于本人先在pycharm(环境:python3.8)中运行代码,再复制到leetcode中提交,所以会出现报错NameError: name 'List' is not defined
。查资料可知,在python3.5后引入了一个typing模块,来增强代码的易读性。
因此,需要在头部导入typing
模块即可。
from typing import List