代码随想录算法训练营第二天| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

977.有序数组的平方  

Given an integer array nums sorted in non-decreasing order, return an array of the squares of each number sorted in non-decreasing order.

Example 1:

Input: nums = [-4,-1,0,3,10]

Output: [0,1,9,16,100]

Explanation: After squaring, the array becomes [16,1,0,9,100]. After sorting, it becomes [0,1,9,16,100].

#1 自己看到题目的第一想法 

排列题;暴力解法的话就是循环一遍,得到square的array,即 [16,1,0,9,100],再用快速排列或者归并,时间复杂度是 nlogn。

另一种方法则是使用双指针 left 和 right, 取 nums[left]^2 和 nums[right]^2 中大的存入res中,再l++ / r--。

#2 看完代码随想录之后的想法 

本题为什么会考虑到左右指针呢,主要是因为本题的数组其实是有序的,即使是平方之后也是有序的。

同时,时间复杂度为n,比暴力解的nlogn+n还是小很多的。

#3 收获  

在排序题中,如果本身的数组是有序的,那么可以选用左右指针而非快排/归并。

209.长度最小的子数组  

Given an array of positive integers nums and a positive integer target, return the minimal length of a contiguous subarray [numsl, numsl+1, ..., numsr-1, numsr] of which the sum is greater than or equal to target. If there is no such subarray, return 0 instead.

Example 1:

Input: target = 7, nums = [2,3,1,2,4,3]

Output: 2

Explanation: The subarray [4,3] has the minimal length under the problem constraint.

#1 自己看到题目的第一想法 

暴力解法的话就是 i 从 0 开始,j 从 i 开始,sum i 到 j 的所有元素,看是否大于7,如果大于7,保存 i 到 j 的长度并且停止 j 的循环。时间复杂度为 n^2。

但是在 leetcode 跑也超时了,那么应该怎么降维度呢?

可以使用双指针降维,如果使用双指针,left 和 right,left 从 0 开始,right 从 0 开始,res += right (res 初始值为 0),如果res >= 7 那么 记录  (right - left + 1) 并且 l--,否则 r++。

#2 看完代码随想录之后的想法  

本题的双指针又称滑动窗口。

移动窗口需要考虑的问题:

- 窗口内是什么?

- 如何移动窗口的起始位置?如果窗口内大于target了,起始位置移动。

- 如何移动窗口的结束位置?从起始位置之后移动。

首先要思考 如果用一个for循环,那么应该表示 滑动窗口的起始位置,还是终止位置。如果只用一个for循环来表示 滑动窗口的起始位置,那么如何遍历剩下的终止位置?此时难免再次陷入 暴力解法的怪圈。所以 只用一个for循环,那么这个循环的索引,一定是表示 滑动窗口的终止位置。

#3 收获   

不同于二分搜索, which需要array是有序的,滑动窗口并没有这个要求,不是说看到非有序就不能用了,双指针并没有这个限制。同时,这种做法的 time complexity will be O(N), where ‘N’ is the number of fruits in the input array. The outer for loop runs for all characters, and the inner while loop processes each character only once; therefore, the time complexity of the algorithm will be O(N+N), which is asymptotically equivalent to O(N).

#4 类似题目  

904.水果成篮(opens new window) 和159. Longest Substring with At Most Two Distinct Characters 也是sliding window解决,一开始用了while来做,感觉会比较messy,用for循环内套 while 反而更加的干净和简单。

这两道 sliding window 都是要求 window 内部满足某种条件,并且 window 中 element 数量最多/最少。

76.最小覆盖子串(opens new window)。同上,sliding window的条件是 every character in t (including duplicates) is included in the window,需要返回的是最小的 window长度,和前两道题型几乎一模一样。但是本题需要注意的是如何判断是否包含 t 中的所有元素,这是比较 tricky 的,我一开始试图暴力循环但是会超时。最后解决办法是用一个新的变量 missing 来判断是否全部包含。(438和567 也是类似题)

59.螺旋矩阵II 

Given a positive integer n, generate an n x n matrix filled with elements from 1 to n2 in spiral order.

#1 自己看到题目的第一想法 

没有太大的技术含量,但是写起来不容易。

#2 看完代码随想录之后的想法   

对于这种问题,一定要首先确认左闭右开还是左闭右闭并且在做题过程中牢记这一点就不会越做越乱!

#3 收获    

不加强了左闭右开还是左闭右闭的重要性。

#4 类似题目 

54. Spiral Matrix

你可能感兴趣的:(代码随想录算法训练营第二天| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II)