算法性能分析:
-
关于时间复杂度和空间复杂度的分析(通用)以及递归算法的复杂度分析
理论基础
-
数组是存放在连续内存空间上的相同型数据的集合。
-
因此,增删元素时需要移动后面的元素
704 二分查找
-
index是变量,要放到while内。此处出错,导致index不能动态更新继续查找。
class Solution:
def search(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums)-1
while left<=right:
index = left+(right-left)//2
if nums[index]>target:
right=index-1
elif nums[index]<target:
left=index+1
else:
return index
return -1
35 搜索插入位置
-
实际上与704一样
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
l = 0
r = len(nums)-1
while l <= r:
midIndex = l + (r-l)//2
if nums[midIndex] > target:
r = midIndex-1
elif nums[midIndex] < target:
l = midIndex+1
else:
return midIndex
return l
34 在排序数组中查找元素的第一个和最后一个位置 (medium)
利用二分法找到target对应的index之后,左右滑动找更小或更大的index
为什么需要判断 left-1>=0?(判断right+1<len(nums)也一样)
- 因为需要判断的是nums[left-1] == target,那么首先要保证 left-1不能超过左边界,也就是0。
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
index = self.binarySearch(nums, target)
if index == -1:
return [-1, -1]
left = right = index
while left-1>=0 and nums[left-1] == target:
left -= 1
while right+1 < len(nums) and nums[right+1] == target:
right += 1
return [left, right]
def binarySearch(self, nums, target):
l = 0
r = len(nums)-1
while l <= r:
midIndex = l + (r-l)//2
if nums[midIndex] > target:
r = midIndex-1
elif nums[midIndex] < target:
l = midIndex+1
else:
return midIndex
return -1
二刷时写法:
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
if len(nums) < 1:
return [-1, -1]
found = self.bnarySearch(nums, target)
if found == -1:
return [-1, -1]
l = r = found
while True:
while l > 0 and nums[l] == nums[l - 1]:
l -= 1
while r < len(nums) - 1 and nums[r] == nums[r + 1]:
r += 1
return [l, r]
def bnarySearch(self, nums, target):
l = 0
r = len(nums) - 1
while l <= r:
mid = l + (r - l) // 2
if nums[mid] < target:
l = mid + 1
elif nums[mid] > target:
r = mid - 1
else:
return mid
return -1
69.x 的平方根
自己写的(代码1)问题:超时
- 没有灵活运用二分法,想着将问题尽量构建成最基本的二分法的状态,但是实际上不必要完全一样,重点是逻辑!
- 对应代码:没必要创建一个数组
class Solution:
def mySqrt(self, x: int) -> int:
nums = [i for i in range(x + 1)]
l = 0
r = len(nums) - 1
while l <= r:
mid = l + (r - l) // 2
if nums[mid]*nums[mid] > x:
r = mid - 1
elif nums[mid]*nums[mid] < x:
l = mid + 1
else:
return nums[mid]
return nums[l - 1]
#本地运行可以
if __name__ == '__main__':
x = 0
func = Solution()
print(func.mySqrt(x))
基于二分法逻辑,写出如下代码:
class Solution:
def mySqrt(self, x: int) -> int:
l = 0
r = x
while l <= r:
mid = l + (r - l) // 2
if mid * mid > x:
r = mid - 1
elif mid * mid <= x and (mid + 1) * (mid + 1) > x:
return mid
else:
l = mid + 1
# if __name__ == '__main__':
# x = 0
# func = Solution()
# print(func.mySqrt(x))
367.有效的完全平方数
与#69一样
class Solution:
def isPerfectSquare(self, num: int) -> bool:
l = 0
r = num
while l <= r:
mid = l + (r - l) // 2
if mid * mid > num:
r = mid - 1
elif mid * mid < num:
l = mid + 1
else:
return True
return False
27 移除元素 (双指针)
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
slow = fast = 0
while fast < len(nums):
if nums[fast] != val:
nums[slow], nums[fast] = nums[fast], nums[slow]
slow += 1
fast += 1
return slow
26.删除排序数组中的重复项
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
slow = fast = 1
while slow < len(nums) and nums[slow] != nums[slow-1]:
slow += 1
fast +=1
while fast < len(nums):
if nums[fast] != nums[slow-1]:
nums[slow], nums[fast] = nums[fast], nums[slow]
slow += 1
fast += 1
return slow
- 代码1使用了swap(nums[slow], nums[fast] = nums[fast], nums[slow]),但是需要判断 if nums[fast] != nums[slow-1]:, 这条语句并不直观。
- 若将判断语句改为 if nums[fast] != nums[fast - 1]:,那么就不能使用swap,只能进行赋值操作(nums[slow] = numsfast),如代码2(更倾向这种写法)
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
s = 1
f = 1
while s < len(nums) and nums[s] != nums[s - 1]:
s += 1
f += 1
while f < len(nums):
if nums[f] != nums[f - 1]:
nums[s] = nums[f]
s += 1
f += 1
return s
283.移动零
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
s = f = 0
while f < len(nums):
if nums[f] != 0:
nums[s], nums[f] = nums[f], nums[s]
s += 1
f += 1
return nums
844.比较含退格的字符串
class Solution:
def backspaceCompare(self, s: str, t: str) -> bool:
stack1 = []
stack2 = []
for char in s:
if stack1 and char == '#':
stack1.pop()
else:
if char != '#':
stack1.append(char)
print(stack1)
for char in t:
if stack2 and char == '#':
stack2.pop()
else:
if char != '#':
stack2.append(char)
print(stack2)
return stack1 == stack2
if __name__ == '__main__':
s = "y#fo##f"
t = "y#f#o##f"
func = Solution()
print(func.backspaceCompare(s, t))
Follow up: Can you solve it in
O(n)
time andO(1)
space?A: try follow the comments of https://www.youtube.com/watch?v=96-d8ZPjHeE
977.有序数组的平方
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
ans = []
l = 0
r = len(nums) - 1
while l <= r:
if abs(nums[l]) > abs(nums[r]):
ans.append(nums[l]**2)
l += 1
else:
ans.append(nums[r]**2)
r -= 1
return ans[::-1]
小结:
用vscode刷leetcode:install leetcode extension之后,默认是连接到美版leetcode,想要用中国版本则需要切换一下,然后登录即可。
以#704为例来探究一下python,想要本地运行:
- 首先leetcode核心代码模式下的代码不能直接给出结果,需要手动在 if __name__ == '__main__': 给出测试用例
- 且需要先create an instance of the object of Solution, then use this instance to invoke the method search() (见代码1)
- 如果想加入全局变量 __init__(self, nums, target), 那么就需要在create an instance of the object of Solution那里给出参数(见代码2)
class Solution:
def search(self, nums, target) -> int:
l = 0
r = len(nums) - 1
while l <= r:
mid = l + (r - l) // 2
if nums[mid] > target:
r = mid - 1
elif nums[mid] < target:
l = mid + 1
else:
return mid
return -1
if __name__ == '__main__':
test = [-1,0,3,5,9,12]
target = 9
find = Solution() #need to create an instance first
print(find.search(test, target))
class Solution:
def __init__(self, nums, target) -> None:
self.nums = nums
self.target = target
def search(self, nums, target) -> int:
l = 0
r = len(nums) - 1
while l <= r:
mid = l + (r - l) // 2
if nums[mid] > target:
r = mid - 1
elif nums[mid] < target:
l = mid + 1
else:
return mid
return -1
if __name__ == '__main__':
test = [-1,0,3,5,9,12]
target = 9
find = Solution(test, target) #need to create an instance first
print(find.search(test, target))