977.有序数组的平方
题目链接:力扣
视频链接:双指针法经典题目 | LeetCode:977.有序数组的平方_哔哩哔哩_bilibili
初印象:首先的思路是“求平方+排序”,简洁清晰,但缺点在于时间复杂度为O(n + nlogn) = O(n)。那么,有没有优化的方案呢?
学习提升:之前“二分查找”中使用了双指针的方法,而这道题目可以借鉴。由于数组是有序的,如果全是正数(可以包括0)或者全是负数(可以包括0)那么只需要求平方,不需要排序。但问题麻烦就麻烦在同时有负数和正数时,求平方之后会导致顺序变化。
而这一点也是双指针法的关键所在,由于数组是有序的,所以求平方之后,两头的数值一定是最大的,所以只需要从两边向中间逐个比较左右两边的数值大小,将较大的数从后向前放入结果数组。
这里我设了一个flag用来指示当前应该插入结果数组的位置。
# 暴力破解
class Solution(object):
def sortedSquares(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
results = []
for num in nums:
results.append(num ** 2)
results.sort()
return results
# 双指针法
class Solution(object):
def sortedSquares(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
num_len = len(nums)
results = range(0,num_len)
flag = num_len - 1
leftindex = 0
rightindex = num_len - 1
while leftindex <= rightindex and flag >= 0:
left_num = nums[leftindex] ** 2
right_num = nums[rightindex] **2
if left_num < right_num :
results[flag] = right_num
rightindex -= 1
else:
results[flag] = left_num
leftindex += 1
flag -= 1
return results
复杂度分析:暴力破解法O(nlogn)、双指针法O(n)
209.长度最小的子数组
题目链接:力扣
视频链接:拿下滑动窗口! | LeetCode 209 长度最小的子数组_哔哩哔哩_bilibili
初印象:刚开始拿到题目,觉得有些复杂,尤其是要找到长度最小的子数组,排列组合的知识突然攻击我(>_<!)。冷静下来之后,看到可以对数组中的元素进行挨个搜索,使用一个for循环和一个while循环来解决,for循环用来遍历数组中的每个元素,while循环用来确定每个元素满足条件的最短连续子数组。
学习提升:学习了代码随想录中的滑动窗口之后,有种豁然开朗的感觉。分析了一下,滑动窗口适用于需要连续的子数组满足一定的逻辑条件的问题,能够一边判断,一边移动窗口,将两个循环简化为一个循环。
# 暴力破解法,下次刷的时候补!
# 滑动窗口法
class Solution(object):
def minSubArrayLen(self, target, nums):
"""
:type target: int
:type nums: List[int]
:rtype: int
"""
i = 0
sub_sum = 0
results = len(nums)
for j in range(len(nums)):
sub_sum += nums[j]
while sub_sum >= target:
subL = j - i + 1
results = min(results,subL)
sub_sum -= nums[i]
i += 1
if i == 0:
return 0
else:
return results
复杂度分析:暴力破解法O(n^2)、 滑动窗口法O(n)
59.螺旋矩阵II
题目链接:力扣
视频链接:一入循环深似海 | LeetCode:59.螺旋矩阵II_哔哩哔哩_bilibili
初印象:题目意思很容易理解,而且思路也并不复杂,但是就是简单的操作需要重复做,麻烦。属于是想起来好像很简单,但是实现起来有些繁琐,特别容易出错。
学习提升:从代码随想录中学到的“循环不变原则”非常有用,由于每一步得到规则是统一的,因此,在处理边界的时候,能够很好地避免出错,整个按照这个思路写下来,十分清晰,不得不说,循环不变原则yyds!
class Solution(object):
def generateMatrix(self, n):
"""
:type n: int
:rtype: List[List[int]]
"""
startx = 0
starty = 0
offset = 1
loop = n / 2
count = 1
results = [[0] * n for _ in range(n)]
for _ in range(loop):
i = startx
j = starty
# 从左向右
while j < n -offset:
results[i][j] = count
count += 1
j += 1
# 从上向下
while i < n -offset:
results[i][j] = count
count += 1
i += 1
# 从右向左
while j > starty:
results[i][j] = count
count += 1
j -= 1
# 从下向上
while i > startx:
results[i][j] = count
count += 1
i -= 1
startx += 1
starty += 1
offset += 1
if n % 2 == 1:
results[loop][loop] = n ** 2
return results
复杂度分析:O(n^2)