977.初想法:先判断数组有没有负数,若有则平方后插入适当位置,没有就正常平方。但是敲不出来。第二次思考:所有数先平方,再来判断是否是非递减排序,第一个数是否大于第二个数……但时间复杂度好像超了。想到后来这题不就是在考察一个时间复杂度为O(n)的排序方法吗,但是我不记得了。看看解答吧。
看完视频:双指针解法:两个指针一头一尾夹着移动对比,更大的元素放在新数组的末尾,当两个指针相遇时循环结束(为什么不在循环里写指针自加或者自减?因为指针自加或者自减是有条件的即在对比大小取一头的指针之后此处的指针才会有自加或自减)。我试试。
class Solution {
public int[] sortedSquares(int[] nums) {
for(int i = 0,k = 0,j = nums.length-1;i >= j;){ //当i>=j时循环停止
if(nums[i]*nums[i] < nums[j]*nums[j]){
nums[k] = nums[i]*nums[i];
i++;
k++;
}else{
nums[k] = nums[j]*nums[j];
j--;
k++;
}
}return nums;
}
}
找不出问题在哪了。重新看看解答吧。
class Solution {
public int[] sortedSquares(int[] nums) {
int a[] = new int[nums.length];
for(int i = 0,k = 0,j = nums.length-1;i <= j;){
if(nums[i]*nums[i] < nums[j]*nums[j]){
a[k] = nums[i]*nums[i];
i++;
k++;
}else{
a[k] = nums[j]*nums[j];
j--;
k++;
}
}return a;
}
}
重新定义了一个数组之后,还是报错。为什么不可以从数组的左边开始放呢?
终于想明白了!因为原始数组是非递减,如果存在负数,两边的数进行比较依次放的话,仍然没有达到排序的效果。我再试一次。
class Solution {
public int[] sortedSquares(int[] nums) {
int right = nums.length-1;
int left = 0;
int[] result = new int[nums.length];
int index = result.length-1;
for(;left <= right;){
if(nums[left]*nums[left] > nums[right]*nums[right]){
nums[index] = nums[left]*nums[left];
index--;
++left;
}else{
nums[index] = nums[right]*nums[right];
index--;
--right;
}
}
return result;
}
}
还是不行,为什么!判断里面写错了,引用的是nums,应该是result。再试!就是对的!
体会:要注意新数组索引的关系,是result.length-1而不是nums.length-1!!!
而且要注意是从新数组从后往前排,不然达不到排序的效果!
想法:把所有符合条件的数组找出来,然后再比较数组的长度再输出长度最小的数组。那么怎么实现把所有符合的数组找出来呢?我想的是从第一个元素开始加,如nums[0]和tag对比,nums[0]+nums[1]和tag对比(递归?),以此类推,若成了,则将元素个数放入集合,最后求集合元素的最大值。尝试了半天还是想不到怎么敲代码。看看讲解吧。
视频还没看完,说用两个for暴力求解,我先试试,还是不会,看不懂int.MAX_VALUE的意思。
视频看了两编,自己敲试试。滑动窗口。基本能成功,存在一个小问题,我看了半天。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int i = 0;//滑动窗口起始位置
int sum = 0;
int max = Integer.MAX_VALUE;
for(int j = 0;j <= nums.length-1;j++){
sum += nums[j];
while(sum >= target){
int result = j - i + 1;
sum -= nums[i];
result = Math.min(result , max);
i++;
}
}
if(result > 0){
return result;
}else{
return 0;
}
}
}
为什么返回的时候报错?因为返回result没有全局定义,只在循环里面定义了,记得要在全局定义返回值。全局定义后就不要再在循环里定义了。
还有一个问题,
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int i = 0;//滑动窗口起始位置
int sum = 0;
int result = Integer.MAX_VALUE;
for(int j = 0;j <= nums.length-1;j++){
sum += nums[j];
while(sum >= target){
sum -= nums[i];
result = Math.min(result , j - i + 1);
i++;
}
}
// if(result > 0){
// return result;
// }else{
// return 0;
// }
return result == Integer.MAX_VALUE ? 0 : result;
}
}
为什么最后返回值要这样写呢?什么意思呢?
我看懂了!result == Integer.MAX_VALUE才是判断语句而不是只是Integer.MAX_VALUE。
class Solution {
public int[][] generateMatrix(int n) {
int[][] a = new int[n][n];
int x = 0;
int y = 0;
int k = 1;
int N = n * n;
int[][] b = {{0,1},{1,0},{0,-1},{-1,0}};
int zhuanwan = 0;
while(k <= N){
a[x][y] = k++;
int x_next = x + b[zhuanwan % 4][0];
int y_next = y + b[zhuanwan % 4][1];
if((x_next < n) && y_next < n && y_next >= 0 && a[x_next][y_next] == 0){
x = x_next;
y = y_next;
}else{
zhuanwan++;
x += b[zhuanwan % 4][0];
y += b[zhuanwan % 4][1];
}
}
return a;
}
}
无语。