977. 有序数组的平方
- 暴力解法,就是直接在原数组中进行平方,然后进行排序。这里我采用了两种排序方法:一个是Arrays.sort函数,内部调用的是快速排序。另一个是手写的冒泡排序。前者时间复杂度为O(nlogn),后者是O(n^2)。
- 巧妙方法,就是利用数组最大值在原数组两边的特性,建立左右双指针,向中间遍历数组,将每次对比后的最大值存入新数组中。
class Solution {
public int[] sortedSquares(int[] nums) {
// for(int i = 0; i < nums.length; i++){
// nums[i] *= nums[i];
// }
//一. Arrays工具类排序
//Arrays.sort(nums);
//二. 冒泡排序
// for(int i = 0; i < nums.length; i++){
// boolean flag = true;
// for(int j = 0; j < nums.length - 1 - i; j++){
// if(nums[j] > nums[j + 1]){
// int temp = 0;
// temp = nums[j];
// nums[j] = nums[j+1];
// nums[j+1] = temp;
// flag = false;
// }
// }
// if(flag == true){
// break;
// }
// }
// return nums;
int[] result = new int[nums.length];
int left = 0;
int right = nums.length - 1;
int k = right;
while(left <= right){//注意退出条件
int left_num = nums[left] * nums[left];
int right_num = nums[right] * nums[right];
if(left_num <= right_num){
result[k--] = right_num;
right--;
}else{
result[k--] = left_num;
left++;
}
}
return result;
}
}
209. 长度最小的子数组
思路:本质是拿双指针来实现滑动窗口。对左侧窗口何时添加、去除元素的细节比较难以把握,建议边debug边修改代码。针对其中的while循环,是大于还是大于等于,也考察了对代码的理解程度。
这里只提供本人思考的代码,卡尔哥的代码其实更加的简洁也易懂,他把操作窗口左侧的元素放入了while循环中,会更好理解点。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left = 0;
int right = 0;
int sum = 0;
int min = 100000;
boolean flag = false;
for(; right < nums.length; right++){
sum += nums[right];
if(sum >= target){
flag = true;
while(sum >= target){
//当相等时也要进入循环,因为出循环后会默认增加前一个left元素,如果正好相等其实不用添加,
//所以要进入循环让left多向前一步,sum多加一个元素
sum -= nums[left++];
}
sum += nums[--left];
int len = right - left + 1;
min = len < min ? len : min;
}
}
if(flag){
return min;
}
return 0;
}
}
59. 螺旋矩阵 II
这里我找了两种解法:
- 利用方向向量来表示要移动的方向,每次加上方向向量的距离来移动,好理解
- 使用代码模拟出填充流程,比较难想出代码
class Solution {
public int[][] generateMatrix(int n) {
//1.采用方向向量的形式,这里使用的是传统的坐标
int dx = 1;
int dy = 0;
int x = 0;
int y = 0;
int[][] nums = new int[n][n]; //int型默认为0
for(int i = 1; i <= n * n; i++){
nums[x][y] = i;
int temp_x = (x - dy + n) % n; //x和y向着向量方向移动,每次加1
int temp_y = (y + dx + n) % n; //防止负数取模,需要先加n,再取模
if(nums[temp_x][temp_y] != 0){ //到头,也就是取模会取到第一次操作的数
int temp = dy;
dy = -dx;
dx = temp; //交换dx、dy使得向量90度旋转。因为向量y负数表示向下,所以取负值
}
x -= dy;
y += dx;
}
return nums;
}
}
class Solution {
public int[][] generateMatrix(int n) {
int[][] nums = new int[n][n];
int startx = 0;
int starty = 0;
int offset = 1;
int loop = n / 2;
int mid = n /2;
int count = 1;
int i;
int j;
while((loop--) > 0){
i = startx;
j = starty;
for(j = starty;j < n - offset; j++){
nums[i][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)!=0) {
nums[mid][mid] = count;
}
return nums;
}
}