Leetcode 704二分查找
题目链接:
题目思路:看见题目的第一想法是直接暴力解,for循环直接挨个扫描 ,O(n)的的时间复杂度。但是我发现我大错特错了!这道题用二分查找的方式更简单,快速。
话不多说,这里我们直接附上代码!
def search(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums)-1
while left<=right:
#计算中位索引
mid = (left+right)//2
if target>nums[mid]:
left = mid+1
if target<nums[mid]:
right = mid -1
if target==nums[mid]:
return mid
return -1
首先我们使用一个左右指针分别指向数组的头与尾,这里有一个坑点,right = len(nums)还是len(nums)-1。涉及一个左开右闭和左闭右开的区间问题。
左闭右闭区间:也就是我们图中的例子,顺序是[left....mid-1] (mid) [mid+1....right-1]
左闭右开区间:也就是left=0,right=len(nums)。顺序是[left....mid-1) (mid) [mid+1.....right)
这里我们的while循环退出的条件就是 left==right.
过程中的难点:当我们思路想出来以后写下代码发现可能有死循环的情况。对于这种数据量小的题,我通常是直接画图然后跟着代码一行一行的走,很快可以找到问题,大部分是我们外层的while循环是应该用<还是<=,还有就是我们的mid,为了防止溢出,建议写成mid = left+(right-left)/2
Leetcode 27移除元素
def removeElement(self, nums: List[int], val: int) -> int:
if len(nums)==0 or nums==[]:
return 0
slow = 0
fast = len(nums)-1
while slow < fast:
while slow < fast and nums[slow]!=val:
slow+=1
while slow < fast and nums[fast]==val:
fast-=1
nums[slow],nums[fast] = nums[fast],nums[slow]
if nums[slow]==val:
return slow
else:
return slow+1
快指针的作用:查找新数组需要构成的元素
慢指针的作用:更换数组下标,一旦我们的快指针找到我们需要的元素
坑点:当我写完之后,我个人对这里的return slow和return slow+1有点疑惑。后来重新捋一遍之后发现,当我们退出最外层while loop之后,我们的slow与fast是==的,这就意味着我们指针之前那的元素都是我们最终留下的,但是当下指针所指向的元素也需要判断,如果当下指向的元素等于我们要删除的值,可以直接返回slow,因为nums[0:slow]是取不到当下这个值的hhhh真的是突然开窍了。如果当下的值不等于要删除的值,说明这个值也是我们所需要的,所以是nums[0:slow+1]才能取到。