非科班 基础较差
day2:209,59自己做时都不会
977.力扣题目链接(opens new window)
这道题我自己先想到了暴力解题法,就是先替换乘方的结果,之后排序就可以,或者先对绝对值排序,之后替换乘方。
class Solution {
public int[] sortedSquares(int[] nums) {
// for(int i = 0; i<nums.length-1; i++){
// for(int j = 0;j<nums.length-1-i;j++){
// if(Math.abs(nums[j])>Math.abs(nums[j+1])){
// int temp = nums[j+1];
// nums[j+1] = nums[j];
// nums[j] = temp;
// }
// }
// }
for (int j = 0; j < nums.length; j++) {
nums[j] = nums[j]*nums[j];
}
Arrays.sort(nums);
return nums;
}
}
随想录的双指针法的关键在于,这个非递减顺序的数组,它的最大值只可能是最大的正数或者最大的负数,次大者同样是数组边缘的数比较。所以可以设定头尾两个指针。每个指针依次比较,确立这把大的数是谁,之后该指针移动。同时设立一个新的数组,依次把比较的填入。循环结束的条件是头指针>尾指针,这时候遍历完了整个数组。
class Solution {
public int[] sortedSquares(int[] nums) {
int startIndex = 0;
int endIndex = nums.length-1;
int[] arr = new int[nums.length];
int len = nums.length-1;
while(startIndex <= endIndex){
if(nums[startIndex]*nums[startIndex] >= nums[endIndex]*nums[endIndex]){
arr[len] = nums[startIndex]*nums[startIndex];
startIndex++;
}else{
arr[len] = nums[endIndex]*nums[endIndex];
endIndex--;
}
len--;
}
return arr;
}
}
209:力扣题目链接
这个题我自己一开始做的时候是想先定义一个i,让i代表每轮数组的长度,再定义一个j,让j代表每次从数组的哪里开始想加,最后再定义一个h,让h代表每次相加几个数组的值,真的想了很久,举例也都通过了,结果提交的时候报错超出时间限制/(ㄒoㄒ)/~~,体验了一把堆屎山的感觉。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
for(int i = 0; i<nums.length;i++){
for(int j = 0;j<nums.length-i;j++){
int sum = 0;
int k = j;
int h = 0;
while(h<i+1){
sum = sum + nums[k];
h++;
k++;
}
if(sum >= target){
return i+1;
}
}
}
return 0;
}
}
用滑动窗口的想法,令j等于窗口的尾端,令i等于窗口的开端,这样的话,i从0开始,j从0开始滑动,直到滑动到某一个索引时满足大于等于target的需求,这时我们暂时记录区间长度(j-i+1)作为result,接下来i开始滑动,sum减去nums[i],之后i++。再判断条件,以此循环,直到判断出当j在这个索引时的最小长度,之后跳出while循环,接着再继续for循环j再++,再进行判断,最终遍历完以后,得出最小的result值。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int result = nums.length+1;
int i = 0;
int sum = 0;
for(int j = 0; j<nums.length;j++){
sum = sum + nums[j];
while(sum >= target){
result = Math.min(result,j-i+1);
sum = sum - nums[i];
i++;
}
}
return result == nums.length+1? 0:result;
}
}
这道题也是滑动窗口的问题,说人话就是找至多包含两种元素的最长子串,返回其长度。
因为不允许重复,所以做的时候很容易想到hashset或者hashmap。但是注意hashset没有索引,不能像list一样remove在i上的数,所以用hashmap,key作为fruits里面的元素,value记录这个元素出现的次数。这样可以通过put操作不断更新value。
class Solution {
public int totalFruit(int[] fruits) {
int i = 0;
int result = -1;
Map<Integer, Integer> map = new HashMap<>();
for (int j = 0; j < fruits.length; j++) {
map.put(fruits[j],map.getOrDefault(fruits[j],0)+1);
while(map.size() >2){
map.put(fruits[i],map.get(fruits[i]) - 1);
if(map.get(fruits[i]) == 0){
map.remove(fruits[i]);
}
i++;
}
result = Math.max(result,j-i+1);
}
return result;
}
}
59.力扣题目链接
这道题不会做,直接看了答案。发现自己对于二维数组的认识太少了,完全没有思路。随想录的方法还需要考虑n是否为奇数,且对于普通的(m,n)的数组的遍历问题还需要考虑其他。这里我用另外一种方法,我觉得它写的更具有普遍适用性。
class Solution {
public int[][] generateMatrix(int n) {
int i = 0;
int count = 1;
int l = 0,t = 0;
int r = n - 1;
int b = n - 1;
int[][] arr = new int[n][n];
while(true){
for(i = l;i<=r;i++){
arr[t][i] = count++;
}
if(++t>b){break;}
for(i = t;i<=b;i++){
arr[i][r] = count++;
}
if(--r<l){
break;
}
for(i = r;i>=l;i--){
arr[b][i] = count++;
}
if(--b < t){
break;
}
for(i = b;i>=t;i--){
arr[i][l] = count++;
}
if(++l > r){
break;
}
}
return arr;
}
}
对于(m,n)的数组,想要螺旋遍历,可以有以下思路: