长度最小子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其总和大于等于 target 的长度最小的
子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:
输入:target = 4, nums = [1,4,4]
输出:1
示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0
首先想到子数组是连续的,从头遍历,遇到满足条件,记录对应长度,然后遍历下一个字符,总耗时是 o ( N 2 ) o(N^2) o(N2)。
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
n = len(nums)
i = 1
k = n+1
for i in range(n):
res = nums[i]
if res>=target:
k=1
break
for j in range(i+1,n):
res += nums[j]
if res >=target:
k = min(k,j-i+1)
break
return k if k<=n else 0
该方法会超过时间限制,循环过程中并没有利用到上一次循环的结果,存在计算浪费。
另一种思路,考虑整个序列满足条件的话,去掉左边或者右边端点元素后,二次判断,满足条件的子序列一定在两者其一,采用归并方法直到找到无法去除端点元素的子序列。
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
if sum(nums) < target:
return 0
def xx(nums):
n = len(nums)
if sum(nums)<target:
return n+1
else:
return min(xx(nums[1:n]),xx(nums[0:n-1]))
return xx(nums)
再换思路,从头遍历子序列,有发现满足条件子序列,从子序列头开始判断,去掉后是否满足,满足条件的k值添加到新列表中,最后返回列表最小值,AC通过.
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
k = res = 0
ret = []
for i in range(len(nums)):
res += nums[i]
k += 1
if res >=target:
ret.append(k)
while (res-nums[i-k+1])>=target and k>1:
res -= nums[i-k+1]
k -= 1
ret.append(k)
return min(ret) if sum(nums)>=target else 0
参考答案,采用双指针滑动窗口。和上述思想基本相似。
- 优化了最小长度判别条件:每次满足条件后,比较最小长度大小。
- 去除最左边元素,采用left指针,left可复用,当此跳出循环后,left为下一次循环左边值,避免进一步循环。
class Solution:
def minSubArrayLen(self, s: int, nums: List[int]) -> int:
l = len(nums)
left = 0
right = 0
min_len = float('inf')
cur_sum = 0 #当前的累加值
while right < l:
cur_sum += nums[right]
while cur_sum >= s: # 当前累加值大于目标值
min_len = min(min_len, right - left + 1)
cur_sum -= nums[left]
left += 1
right += 1
return min_len if min_len != float('inf') else 0
螺旋矩阵
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例 1:
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入:n = 1
输出:[[1]]
未找到规律,参考模拟矩阵方法,模拟整个向内环绕的填入过程。当前左右上下边界 l , r , t , b l,r,t,b l,r,t,b,初始值 i = 1 i= 1 i=1,迭代终止值 n ∗ n n * n n∗n,而不是 l < r ∣ ∣ t < b l < r || t < b l<r∣∣t<b作为迭代条件,是为了解决当 n n n为奇数时,矩阵中心数字无法在迭代过程中被填充的问题。
-
时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n n n 是给定的正整数。矩阵的大小是 n ∗ n n*n n∗n,需要填入矩阵中的每个元素。
-
空间复杂度: O ( 1 ) O(1) O(1)。除了返回的矩阵以外,空间复杂度是常数。
class Solution:
def generateMatrix(self, n: int) -> [[int]]:
l, r, t, b = 0, n - 1, 0, n - 1
i = 1
matrix = [[0] * n for _ in range(n)]
while i <= n * n:
for j in range(l,r+1):
matrix[t][j] = i
i += 1
t += 1
for j in range(t,b+1):
matrix[j][r] = i
i += 1
r -= 1
for j in range(r,l-1,-1):
matrix[b][j] = i
i += 1
b -= 1
for j in range(b,t-1,-1):
matrix[j][l] = i
i += 1
l += 1
return matrix