一、数组理论基础
- 数组下标都是从0开始的
- 数组内存空间的地址是连续的
- 数组的元素是不能删的,只能覆盖
二、刷题
第一题 704.二分查找
题目链接:https://leetcode.com/problems/binary-search/
难度:easy
思路:
题干sorted ascending array ,再加上给一个target返回符合的索引,很显然是需要缩小查找范围——首选二分查找法
再看限制条件,nums长度,时间复杂度最多为O(n^2), 如果用二分查找时间复杂度是O(logn) 符合题目条件
代码:
class Solution: def search(self, nums: List[int], target: int) -> int: # sorted array - BS 目的:缩小查找范围 # l, r l=0 r=len(nums) while l<r: m = l + (r - l)//2 if nums[m] == target: return m elif nums[m]>target: r = m else: l = m+1 return -1
习惯写左闭右开的方法,l<r, 其中r是不可能被遍历到的位置。
时间复杂度:O(logn)
空间复杂度:O(1)
第二题 34.有序数组找首位末位
题目链接:https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/
难度:medium
思路:
non-decreasing order-BS,target
又要求O(log n) ----二分查找
这道题的难点在于:如何确定下边界和上边界,怎么缩小范围,初刷没做出来,看答案看懂的。
代码:
class Solution: def searchRange(self, nums: List[int], target: int) -> List[int]: #non-decreasing order-BS,target,lower bound & upper bound #O(log n) ---- 100% BS solution ''''while l<r: if nums[m]>target: r=m if nums[m]<target: l=m+1 if nums[m]==target: l+=1 r-=1 #这道题的难点在于:如何确定下边界和上边界,怎么缩小范围 return [-1,-1]''' def search(x): l, r = 0, len(nums) while l < r: m = l+(r-l) // 2 if nums[m] < x: #这里严格小于缩小范围会得到下边界,同理严格大于缩小范围的思路会得到上边界。很tricky的一个细节,要注意! l = m+1 else: r = m return l l = search(target) r = search(target+1)-1 if l <= r: return [l, r] return [-1, -1] ''' [5,7,7,7,7,8,8,8,10] target=8 l=search(8) r=search(9)-1 search(x) l=0,5, r=9,9, m=4,7, nums[m]=7<8 nums[m]=8 expect output[5,7] '''
debug: IndentationError: unexpected indent 缩进不对
时间复杂度:O(logn)
空间复杂度:O(1)
第三题 35.搜索插入位置
题目链接:https://leetcode.com/problems/search-insert-position/
难度:easy
思路:
sorted array+target需要缩小范围搜索,用二分查找
找下边界的题,都是一个套路模版,和34题几乎一样
class Solution: def searchInsert(self, nums: List[int], target: int) -> int: l=0 r=len(nums) while l<r: m=l+(r-l)//2 if nums[m]<target: l=m+1else: r=m return l
时间复杂度:O(logn)
空间复杂度:O(1)
第四题 27.移除元素
题目链接:
https://leetcode.com/problems/remove-element/
难度:easy
思路:
要求对等于val的值被替换成其他的,剩下的不管。那就只用遍历一遍,等于va的都跳过,不等于的值才可以按顺序被替换进array,剩下的位置都是空
class Solution: def removeElement(self, nums: List[int], val: int) -> int: p=0 for i in range(len(nums)): if nums[i]==val: continue nums[p]=nums[i] p+=1 return p
时间复杂度:O(n)
空间复杂度:O(1)
总结:
今天刷了4道题,704,34,35都是BS,27很简单 算不上two pointers.
熟练掌握了二分查找寻找下边界的模版
学习时长2小时,效果还不错,再接再厉。