day2|leetcode 977、209、904、59

非科班 基础较差

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;
    }
}

904

这道题也是滑动窗口的问题,说人话就是找至多包含两种元素的最长子串,返回其长度。

因为不允许重复,所以做的时候很容易想到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)的数组,想要螺旋遍历,可以有以下思路:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值