基本概念
-
时间复杂度:时间复杂度的计算并不是计算程序具体运行的时间,而是算法执行语句的次数。
-
空间复杂度:空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度。
-
使用二分法的前提:
- 数组为有序数组
- 数组中无重复元素
704. 二分查找
- 题目链接:704. 二分查找 - 力扣(LeetCode)https://leetcode.cn/problems/binary-search/description/
class Solution: def search(self, nums: List[int], target: int) -> int: left, right = 0, len(nums) while left < right: middle = left + (right-left) // 2 if nums[middle] > target: right = middle elif nums[middle] < target: left = middle + 1 else: return middle return -1
一开始 return middle 写成了 Else : nums[middle] = target , 爆超时因为没有return。
下面我们来看一下二分法的两个迭代法的时间复杂度和空间复杂度:
时间复杂度:时间复杂度的计算并不是计算程序具体运行的时间,而是算法执行语句的次数。
假设总共有n个元素,每次查找的区间大小就是n,n/2,n/4,…,n/2^k,其中k就是循环的次数,
n/2^k >= 1(1最坏的情况,即还剩一个元素),
令n/2^k=1,
可得k=log2n(以2为底,n的对数),
所以时间复杂度可以表示O(log2n)。
空间复杂度:空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度。
因为变量只创建一次,所以空间复杂度为O(1)。
27. 移除元素
时间复杂度O(n^2)
空间复杂度:O(1)
(版本二)暴力法
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
i, l = 0, len(nums)
while i < l:
if nums[i] == val: # 找到等于目标值的节点
for j in range(i+1, l): # 移除该元素,并将后面元素向前平移
nums[j - 1] = nums[j]
l -= 1
i -= 1
i += 1
return l
时间复杂度:O(n)
空间复杂度:O(1)
(版本一)快慢指针法
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
# 快慢指针
fast = 0 # 快指针
slow = 0 # 慢指针
size = len(nums)
while fast < size: # 不加等于是因为,a = size 时,nums[a] 会越界
# slow 用来收集不等于 val 的值,如果 fast 对应值不等于 val,则把它与 slow 替换
if nums[fast] != val:
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow
要注意return slow 前面的tab 要跑完while出来才return
#206 反转列表
206. 反转链表 - 力扣(LeetCode)https://leetcode.cn/problems/reverse-linked-list/submissions/534540670/
(版本一)双指针法
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
cur = head
pre = None
while cur:
temp = cur.next # 保存一下 cur的下一个节点,因为接下来要改变cur->next
cur.next = pre #反转
#更新pre、cur指针
pre = cur
cur = temp
return pre
一刷还是老实慢悠悠写双指针,递归并没有看懂也不会写。。
(版本二)递归法
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
return self.reverse(head, None)
def reverse(self, cur: ListNode, pre: ListNode) -> ListNode:
if cur == None:
return pre
temp = cur.next
cur.next = pre
return self.reverse(temp, cur)
除非面试官要求你用递归完成,不然还是老是写双指针。。。