一. Leetcode 977: 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。有序数组的平方
第一种简单方法就是利用两个for loop 进行暴力求解, 所需时间复杂度是O(N^2). 另外一种可行的方法是可以自定义一个求平方函数 (e.g., lambda x: x^2), 然后把这个function运用到这个数组上。之后在进行sort, 总的时间复杂度是O(2N), 即O(N)。
下面介绍一种双指针的方法,也可以实现O(N)。具体代码如下:
nums = [-7,-3,2,3,11] # 指定数组
res = [0]*len(nums) # 建立空数组
pin_left = 0 # 左指针
pin_right = len(nums)-1 # 右指针
k = len(nums)-1 # res的初始循环索引
while pin_left<=pin_right: # 循环条件
if nums[pin_left]**2 > nums[pin_right]**2: # 左边的大于右边的
res[k] = nums[pin_left]**2
pin_left+=1 # 向右滑动左指针
else: # 左边的小于等于右边的
res[k] = nums[pin_right]**2
pin_right-=1 # 向左滑动右指针
k -=1 # 逆向调整res的循环索引
注意:观察数组可以看出数组元素两边的平方数值要大于中间的元素平方的数值,因此定义两个指针分别放在数组的一端,向中间滑动,滑动的过程当中,去比较两端元素的平方,然后取最大值,以逆序放入空数组里。两指针都向中间滑动,所以必然产生交际元素。因此,当左指针索引大于有指针索引的时候,循环停止。
一. Leetcode 209: 给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 ,并返回其长度。如果不存在符合条件的子数组,返回 0 。长度最小的子数组
首先此题有暴力解法。通过两个for loop去寻找长度最小的子数组。代码如下:
target = 7
nums1 = [2,3,1,2,4,3] # 给定数组
res = [] # 建立空数组
#1. 暴力解法
for i in range(len(nums1)): #
if i == len(nums1)-1:
if nums1[i]==target:
res.append(len([nums1[i]]))
else:
num_part = nums1[i + 1:len(nums1) + 1] # 切割每个i之后的剩下数组的元素
k = 0 # 循环剩余部分的初始系数
combin_arr = [nums1[i]] + num_part
while k <= len(num_part)-1:
if sum(combin_arr) >= target:
res.append(len(combin_arr))
combin_arr.pop()
print(combin_arr)
k += 1
if res == []:
result = 0
else:
result = min(res)
此暴力方法在代码叙述上有点繁琐,所以大家随意看下就行。接下来重点陈述滑动窗口的方法,本质上是双指针的变形,毕竟滑动窗口的两个边界是可以移动的,相当于两个指针。首先要明确的是‘滑动窗口’对于此题的意义: 扫描数组的子集合。下一个问题就是滑动窗口应该怎么移动?换句话说两个指针(数组索引)怎样来移动?它们的起始位置在哪里?介于题目没有具体的要求,我们可以从数组起始位置开始。
先固定慢指针,然后移动快指针,每当快指针扫过一个元素的时候,我们需要判断当前滑动窗口数组元素之和是否大于/等于目标值,如果小于的话,那快针继续前行。知道有符合条件的数组出现,然后记录一下数组的长度,并取最小值。注意,这个时候,快针不应该继续前行了,因为题目明确告诉我们要取最小元素之和的数组长度。继续累加的话,数组长度会更长的,没有意义。因此当这个条件出现的时候,我们就需要从下一个元素开始继续寻找符合条件的数组了,因此,慢针需要向前走一步。当快针索引到了最后一个元素的情况下,在此基础上,慢针也停止走了,那滑动窗口任务彻底完成。代码如下:
nums2 = [2,3,1,2,4,3]
start_pin = 0 # 慢针
end_pin = 0 # 快针
target1 = 7
sum_window = 0
res2 = sum(nums2) # 最大值初始化
while end_pin <=len(nums2)-1: # 当快针没到数组末端元素索引的时候,循环一直进行
sum_window += nums2[end_pin] # 累加元素,并求和
while sum_window >= target1: # 累加完之后,判定当前值是否大于等于目标值
length_window = end_pin-start_pin+1 # 进入判定,取数组长度
res2 = min(sum_window, length_window) #求数组最小值
sum_window-= nums2[start_pin] #取完最小值之后,去掉前一个慢指针所指的元素。
start_pin+=1 # 慢指针向前走一步
end_pin+=1 # 快针累加
注意:在数组中,‘指针’的意思就是代表元素的索引。