977.有序数组的平方
思路分析
一、暴力解法
- 先创建一个与 传进来的nums数组长度 一样的新数组arr
- 通过一层for循环去遍历nums数组,定义一个变量number,根据nums数组的下标拿到相对应的元素 赋值给变量number(其实也可以不用,就是定义变量能更加简洁,不容易搞错,因为有两个数组)
- 将变量number平方赋值给新数组的对应下标的元素
- 退出循环,将新数组arr的元素进行排列(Java的util包中有一个类->Arrays类)
- 最后返回排列好的新数组arr
二、双指针法
- 首先定义两个指针 left 和 right,分别代表 数组的起始位置 和 数组的最后位置
- 定义一个新的数组来存放元素,新数组长度 与 传进来的数组 的长度要保持一致,之后定义一个指向新数组下标的变量index,把这个变量放到新数组的最后位置(之后的while循环中,通过 传进来的数组 中 两个指针指向的值 比较大小,大的值就放在后面->即从右往左填充数据)
- while循环,条件是左闭右闭 left <= right
- 通过if判断语句,如果right指针指向的值比left指针指向的值大,则赋值给新数组中index位置,right指针需要往前移动->right--,index变量也需要往前移动index--(容易忘记)
- 如果 left 指针指向的值比 right 指针指向的值大,则赋值给新数组中index位置,left 指针需要往前移动-> left++,index变量也需要往前移动index--(容易忘记)
- 最后返回arr数组
代码实现(Java)
//暴力解法
class Solution {
public int[] sortedSquares(int[] nums) {
int[] arr = new int[nums.length];
for(int i = 0;i < nums.length;i++){
int number = nums[i];
arr[i] = number * number;
}
Arrays.sort(arr);
return arr;
}
}
//双指针法
class Solution {
public int[] sortedSquares(int[] nums) {
int left = 0;
int right = nums.length - 1;
int[] arr = new int[nums.length];
int index = arr.length - 1;
while(left <= right){
if(nums[right] * nums[right] > nums[left] * nums[left]){
arr[index] = nums[right] * nums[right];
right--;
index--;
}else{
arr[index] = nums[left] * nums[left];
left++;
index--;
}
}
return arr;
}
}
209.长度最小的子数组
题目链接:. - 力扣(LeetCode)
题目描述
给定一个含有
n
个正整数的数组和一个正整数target
。找出该数组中满足其总和大于等于
target
的长度最小的 连续子数组
[numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度。如果不存在符合条件的子数组,返回0
。
思路分析
一、暴力解法
- 两个for循环,然后不断的寻找符合条件的子序列
- 时间复杂度是O(n^2)
二、滑动窗口
- 先定义一个指向数组起始位置的变量 left 和 滑动窗口的总和 sum
- 初始化 result 变量为 Integer.MAX_VALUE(result变量是为了存储找到的最短子数组的长度)
- 使用一层for循环,以 right 为迭代器,循环内部,将当前元素 nums[right] 添加到 sum 中,当sum 大于或等于 target 时,进入while循环(不能是if,因为要缩小窗口)
- 通过Math类中的min方法,比较 result 和 滑动窗口的长度 ,取两者间的最小值,更新 result
- 然后从 sum 中减去 nums[left](从左侧缩小窗口),left 一定要向前移动。直到sum小于target时,退出循环
- 循环结束后,检查 result 是否仍然是 Integer.MAX_VALUE。如果是,则意味着没有找到满足要求的子数组,返回0;否则,则返回 result
代码实现(Java)
//暴力解法
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int result = INT32_MAX; // 最终的结果
int sum = 0; // 子序列的数值之和
int subLength = 0; // 子序列的长度
for (int i = 0; i < nums.size(); i++) { // 设置子序列起点为i
sum = 0;
for (int j = i; j < nums.size(); j++) { // 设置子序列终止位置为j
sum += nums[j];
if (sum >= s) { // 一旦发现子序列和超过了s,更新result
subLength = j - i + 1; // 取子序列的长度
result = result < subLength ? result : subLength;
break; // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break
}
}
}
// 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
return result == INT32_MAX ? 0 : result;
}
};
//滑动窗口
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left = 0;
int sum = 0;
int result = Integer.MAX_VALUE;
for(int right = 0;right < nums.length;right++){
sum = sum + nums[right];
while(sum >= target){
result = Math.min(result,right - left + 1);
sum = sum - nums[left];
left++;
}
}
return result == Integer.MAX_VALUE ? 0:result;
}
}
59.螺旋矩阵II
题目链接:. - 力扣(LeetCode)
题目描述
给你一个正整数
n
,生成一个包含1
到n2
所有元素,且元素按顺时针顺序螺旋排列的n x n
正方形矩阵matrix
。
思路分析
- 创建一个n x n的二维数组来存储螺旋矩阵。
int startX = 0, startY = 0;
设置起始点的坐标,初始为(0,0)。int offset = 1;
设置偏移量,用于控制每一圈螺旋的边界。int count = 1;
设置计数器,用于填充矩阵中的数字。int loop = 1;
设置循环计数器,用于控制螺旋的圈数。int i, j;
定义循环变量i和j,分别代表行和列。
接下来是一个while循环,用于生成螺旋矩阵:
while (loop <= n / 2)
循环直到loop大于n/2,这意味着完成了所有完整的螺旋圈。
在循环内部,分别处理四个方向:
for (j = startY; j < n - offset; j++) { nums[startX][j] = count++; }
填充当前圈的最上面一行,从左到右。for (i = startX; i < n - offset; i++) { nums[i][j] = count++; }
填充当前圈的右面一列,从上到下。for (; j > startY; j--) { nums[i][j] = count++; }
填充当前圈的最下面一行,从右到左。for (; i > startX; i--) { nums[i][j] = count++; }
填充当前圈的左面一列,从下到上。
每次循环结束后,更新起始点坐标和偏移量:
startX++;
startY++;
offset++;
loop++;
分别将起始点坐标向内移动,增加偏移量,并增加圈数。
最后,如果n是奇数,中心位置需要单独处理:
if (n % 2 == 1) { nums[startX][startY] = count; }
在矩阵中心填入最后一个数字。
最后,返回填充好的二维数组nums
。
代码实现(Java)
class Solution {
public int[][] generateMatrix(int n) {
int[][] nums = new int[n][n];
int startX = 0, startY = 0; // 每一圈的起始点
int offset = 1;
int count = 1; // 矩阵中需要填写的数字
int loop = 1; // 记录当前的圈数
int i, j; // j 代表列, i 代表行;
while (loop <= n / 2) {
// 顶部
// 左闭右开,所以判断循环结束时, j 不能等于 n - offset
for (j = startY; j < n - offset; j++) {
nums[startX][j] = count++;
}
// 右列
// 左闭右开,所以判断循环结束时, i 不能等于 n - offset
for (i = startX; i < n - offset; i++) {
nums[i][j] = count++;
}
// 底部
// 左闭右开,所以判断循环结束时, j != startY
for (; j > startY; j--) {
nums[i][j] = count++;
}
// 左列
// 左闭右开,所以判断循环结束时, i != startX
for (; i > startX; i--) {
nums[i][j] = count++;
}
startX++;
startY++;
offset++;
loop++;
}
if (n % 2 == 1) { // n 为奇数时,单独处理矩阵中心的值
nums[startX][startY] = count;
}
return nums;
}
}