有序数组的平方
题目:给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
思路:使用双指针,因为新的平方数组,最大数一定出在两端,所以可以有两个指针,指向两端,向中间靠拢。
class Solution {
public int[] sortedSquares(int[] nums) {
int[] newNums = new int[nums.length];
int left = 0;
int right = nums.length -1;
int index = nums.length -1;
while(left<=right){
if(nums[left]*nums[left]>nums[right]*nums[right]){
newNums[index--] = nums[left]*nums[left];
left++;
}else{
newNums[index--] = nums[right]*nums[right];
right--;
}
}
return newNums;
}
}
长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
题目:找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
思路:使用滑动窗口。所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。只用一个for循环,这个循环的索引,一定是表示 滑动窗口的终止位置。窗口是 满足其和 ≥ s 的长度最小的 连续 子数组。如果当前窗口的值大于目标值了,窗口就要向前移动了(也就是该缩小了)。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left=0;
int sum = 0;
int len = Integer.MAX_VALUE;
for(int right = 0;right <nums.length;right++){
sum += nums[right];
while(sum >= target){
len = Math.min(len, right - left + 1);
sum -= nums[left++];
}
}
return len==Integer.MAX_VALUE?0:len;
}
}
- 时间复杂度:O(n)
- 空间复杂度:O(1)
不要以为for里放一个while就以为是O(n^2)啊,
主要是看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n
也就是O(n)。
螺旋矩阵Ⅱ
题目:给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
图:
思路:关键点是确定不变量,也就是左闭右闭还是左闭右开。
class Solution {
public int[][] generateMatrix(int n) {
int[][] nums = new int[n][n];
int startX = 0;
int startY = 0;
int mid = n/2;
int loop = n/2;
int offset = 1;
int count = 1;
int i = 0;
int j = 0;
while(loop-- > 0){
i = startX;
j = startY;
for(j = startY; j<n - offset;j++){
nums[startX][j] = count++;
}
for(i = startX; i < n -offset ;i++){
nums[i][j] = count++;
}
for( ; j > startX; j--){
nums[i][j] = count++;
}
for( ; i > startY; i--){
nums[i][j] = count++;
}
startX++;
startY++;
offset++;
}
if(n%2 == 1){
nums[mid][mid] = count;
}
return nums;
}
}