一 977 有序数组的平方
典型的双指针类题目,给定的数组本身就是有序的,不能浪费这个条件,平方最大的值必定是正数中最大的值或者是负数中最小的值,正好位于数组的两端,因此采用双指针可以有效减少时间复杂度。
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int left = 0,right = nums.size() - 1;
vector<int> ans(nums.size(),0);
for(int k = nums.size() - 1; k >= 0; k--){
if(nums[left] * nums[left] > nums[right] * nums[right]){
ans[k] = nums[left] * nums[left];
left++;
}
else{
ans[k] = nums[right] * nums[right];
right--;
}
}
return ans;
}
};
class Solution {
public int[] sortedSquares(int[] nums) {
int left = 0,right = nums.length - 1;
int [] ans = new int[nums.length];
for(int k = nums.length - 1; k >= 0; k--){
if(nums[left] * nums[left] >= nums[right] * nums[right]){
ans[k] = nums[left] * nums[left];
left++;
}
else{
ans[k] = nums[right] * nums[right];
right--;
}
}
return ans;
}
}
class Solution(object):
def sortedSquares(self, nums):
left,right,k = 0,len(nums) - 1,len(nums) - 1
ans = [0]*len(nums)
while k >= 0:
if nums[left] ** 2 >= nums[right] ** 2:
ans[k] = nums[left] ** 2
left += 1
else:
ans[k] = nums[right] ** 2
right -= 1
k -= 1
return ans;
二 209 长度最小的子数组
属于双指针中的滑动窗口问题,一般来说对数组中的值是有一定要求的,尤其是求和大于target值时会要求数组中的元素非负。其重点在于:什么时候右指针移动,什么时候左指针移动,什么时候收取结果。
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int left = 0,right = 0;
int len = nums.size() + 1;
int sum = 0;
while(right < nums.size()){
sum += nums[right];
while(sum >= target){
len = min(len,right - left + 1);
sum -= nums[left];
left++;
}
right++;
}
if(len == nums.size() + 1)
return 0;
return len;
}
};
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left = 0,right = 0;
int len = nums.length + 1;
int sum = 0;
while(right < nums.length){
sum += nums[right];
while(sum >= target){
len = Math.min(len,right - left + 1);
sum -= nums[left];
left++;
}
right++;
}
if(len == nums.length + 1)
return 0;
return len;
}
}
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
left,right = 0,0
numslen = len(nums) + 1
sum = 0
while right < len(nums):
sum += nums[right]
while(sum >= target):
numslen = min(numslen,right - left + 1)
sum -=nums[left]
left += 1
right += 1
if numslen == len(nums) + 1:
return 0
return numslen
三 59 螺旋矩阵
类似的这种问题,难度在于边界值的判断以及循环变量的选择上,在有关的模拟输出类题目中一定要坚持循环不变量原则,按照固定规则来遍历。
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> ans(n, vector<int>(n, 0));
int cycle = n/2;
int count = 1;
int offset = 1;
for(int i = 1; i <= cycle ; i++){
int startx = i - 1;
int starty = i - 1;
for(int j = startx; j < n - offset; j++){
ans[starty][j] = count++;
}
for(int k = starty; k < n - offset; k++){
ans[k][n - offset] = count++;
}
for(int j = n - offset; j > startx; j-- ){
ans[n - offset][j] = count++;
}
for(int k = n - offset ; k > starty; k--){
ans[k][starty] = count++;
}
offset++;
}
if(n % 2 == 1)
ans[cycle][cycle] = n*n;
return ans;
}
};
四 总结
- python中/是除法,//是整除向下取整
- python中列表初始化可以通过ans = [0]*len(nums)申请固定位数的列表
- python中inf表正无穷
- python中关于长度的变量名不能起为len,因为有len()函数