70.爬楼梯问题
很明显这是一个动态规划的问题,第一层楼梯有一种解法,第二层有两种解法,第三层楼梯有三种解法,而第四层楼梯有五种解法,得到下面的解题公式:
f
(
n
)
=
f
(
n
−
1
)
+
f
(
n
−
2
)
f(n) = f(n-1) + f(n-2)
f(n)=f(n−1)+f(n−2) 合理推理得下面的解法:
class Solution:
def climbStairs(self, n: int) -> int:
if n == 1:
return 1
elif n == 2:
return 2
else:
return self.climbStairs(n - 1) + self.climbStairs(n - 2)
但这种解法居然是超时的,也就是说,我们没有很好的考虑到时间复杂度与空间复杂度,类似树一样,当有很多大数计算的时候,进行了重复的运算,所以需要对这棵树进行剪枝。
class Solution:
def climbStairs(self, n: int) -> int:
i = 1
j = 2
for _ in range(3, n):
i, j = j, i + j
return i + j if n > 2 else n
往往单层遍历就是最好的剪枝手段,这样的时间复杂度可以堪称是O(n)
,空间复杂度可以看成是O(1)
。
15.三数之和
双指针问题,也就是说左右两边都有指针,着两个指针分别指向的是最右边以及最左边,遍历有一个for
循环,for
循环中是中间指针所移动的方向,那么两个指针分别向中间收敛,判断依据是两个指针位置不相等!
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
if len(nums) < 3:
return []
res = []
nums.sort()
for i in range(len(nums) - 2):
if i > 0 and nums[i] == nums[i - 1]:
continue
l, r = i + 1, len(nums) - 1
while l < r :
s = nums[i] + nums[l] + nums[r]
if s < 0:
l += 1
elif s > 0:
r -= 1
else:
res.append((nums[i], nums[l], nums[r]))
while l < r and nums[l] == nums[l+1]:
l += 1
while l < r and nums[r] == nums[r-1]:
r -= 1
l += 1
r -= 1
return res
16.最接近的三数之和
双指针问题升级版,考虑到差值问题
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
n = len(nums)
nums.sort()
re_min = 0 # 存储当前的最小差值
for i in range(n):
l = i + 1
r = n - 1
while l < r:
three_sum = nums[i] + nums[l] + nums[r]
diff = target - three_sum
if re_min == 0:
re_min = abs(diff)
sum_min = three_sum
if abs(diff) < re_min:
re_min = abs(diff)
sum_min = three_sum
if three_sum == target:
return target
elif three_sum < target:
l += 1
else:
r -= 1
return sum_min
206.反转链表
可以说,思路异常简单,我们仅需要三个节点,这三个节点分别是cur(当前节点)、cur.next(当前节点的下一个节点)、pre(前向节点),这三个节点的关系是:
pre, cur = None, head
cur.next, pre, cur = pre, cur, cur.next
为什么是这样的关系呢?看下step的情况,以下面的A->B->C->D->E来表示,
- step1:cur = A,cur.next = None, pre = A, cur = B
- step2:cur.next = A,pre = B,cur = C
- …
- 如此反复,得到下面的代码
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
cur, prev = head, None
while cur:
cur.next, prev, cur = prev, cur, cur.next
return prev
344.反转字符串
解法如下:
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
l , r = 0, len(s) - 1
while l < r:
s[l], s[r] = s[r], s[l]
l += 1
r -= 1
return s