给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
示例 2:
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]
nums
已按 非递减顺序 排序- 请你设计时间复杂度为
O(n)
的算法解决本问题
双指针算法 (O(N)时间复杂度)
case1: 数组里面全部是正数
case2: 数组里面左半边是负数,右半边是正数
case3: 数组里面全部都是负数
如何把这几个case全部整合到一起?
1.双指针,一个从头遍历,一个从尾遍历;
2.定义一个长度为 len(nums)的res数组
3.设置一个pos参数,pos = len(nums) - 1,逆序遍历
4. 两个指针对应的数值的平方进行比较,谁大,就放在pos的位置上,pos 不断的 -1
如果是l指针大就 l+=1,如果是r指针大就 r-=1
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
n = len(nums)
l,r = 0, len(nums)-1
pos = len(nums) - 1
res = [-1] * n
while pos >= 0: # 这里最tricky的地方就是其实pos可以取到0
if nums[l] * nums[l] > nums[r] * nums[r]:
res[pos] = nums[l] * nums[l]
l += 1
elif nums[l] * nums[l] <= nums[r] * nums[r]:
res[pos] = nums[r] * nums[r]
r -= 1
pos -= 1
return res
易错点:
1. while 循环的终止条件应该是 while pos >= 0, 因为 pos 可以取到 0 的位置!!!
给定一个含有 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
# 初步思路:
使用deque来表示滑窗,同时使用cur_sum来统计窗口元素的和,如果 >= target, 就把窗口左侧向右移动;如果还没有达到target,就把窗口右侧不断向右移动
# 深入 思考:
但是窗口的表示,真的需要一个deque吗?本质上是不用的!
因为窗口的存在,是因为它满足了某个条件,在这个题目里,就是让 cur_sum >= target! 因此在这个情况下,我们就并不需要多此一举使用deque,而是可以直接定义cur_sum变量,用它和target的关系来表示窗口动态变化的过程。注意:元素离开窗口的时候,cur_sum -= nums[l] 即 cur_sum要把这个元素给去掉。
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
# O(N) --
# O(N log N) --
cur_sum = 0
l = 0
min_dis = float('inf')
for r in range(len(nums)):
cur_sum += nums[r] # 不管三七二十一,窗口先放元素进来
while cur_sum >= target: # 卧槽:题目是找满足 >= target 而非 = target ..
cur_sum -= nums[l]
min_dis = min(min_dis, r-l+1)
l += 1
return min_dis if min_dis != float('inf') else 0
# 收获:不需要通过 deque 来表示窗口
# 因为窗口形成的本质是满足某一个条件,所以只要让条件满足,其实就是窗口形成 - 好像在说废话
易错点:
1. 窗口形成的条件是 cur_sum >= target 题目不是=target,而是>= target!!!
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例 1:
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入:n = 1
输出:[[1]]
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
maxtrix = [[ n+1 for _ in range(n)] for _ in range(n)] # create a matrix
l,r,t,b = 0,n-1,0,n-1
value = 1
while l <= r and t <= b:
# left to right
for i in range(l,r+1):
maxtrix[t][i] = value
value += 1
t += 1
# top to buttom
for i in range(t,b+1):
maxtrix[i][r] = value
value += 1
r -= 1
# right to left
if t <= b and l <= r: # 为什么如果我在这里写 while 会报错呢?
for i in range(r,l-1,-1):
maxtrix[b][i] = value
value += 1
b -= 1
# bottom to up:
if t <= b and l<= r:
for i in range(b,t-1,-1):
maxtrix[i][l] = value
value += 1
l += 1
return maxtrix
# 易错点:什么时候写while,什么时候写 if ?
1.遍历范围:我选择了左闭右闭的遍历方式,所以要在每个地方都+1或者-1
2.当前两个顺序 t += 1 和 r-=1 的时候,后两段代码就要重新考虑 l <= r 和 t <= b 保证没有越界
3.遍历(右到左,下到上)的时候,我写 while 循环,答案就会报错,只能写 if -- 为哈?