代码随想录算法训练营第二天| 977. 有序数组的平方、209. 长度最小的子数组、5螺旋数组2。

977. 有序数组的平方

题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/

1、代码:

//最容易想到的方法,先把数组的每个数都平方,然后再排序;
class Solution {
    public int[] sortedSquares(int[] nums) {
            for(int i=0;i<nums.length;i++){
                nums[i]=nums[i]*nums[i];
            }

            for(int i=0;i<nums.length-1;i++){
                for(int j=0;j<nums.length-1-i;j++){
                    if(nums[j]>nums[j+1]){
                        nums[j]=nums[j]^nums[j+1];
                        nums[j+1]=nums[j+1]^nums[j];
                        nums[j]=nums[j]^nums[j+1];
                    }
                }
            }
        return nums;

    }
}

这个数组的特点是,两边的平方值比中间的平方大。所以可以用双指针,每次比较左指针指向的值的平方和右指针指向的值的平方的大小,然后把大的那个值放到一个新数组的末尾;

//用指针
class Solution {
    public int[] sortedSquares(int[] nums) {
        int l=0;
        int r=nums.length-1;
        int pos=nums.length-1;
        int[] arr=new int[nums.length];
        while(r>=l){
            if(nums[l]*nums[l]>nums[r]*nums[r]){
                arr[pos]=nums[l]*nums[l];
                l++;
            }else{
                arr[pos]=nums[r]*nums[r];
                r--;
            }
                pos--;
        }

return arr;
    }
}


209、长度最小的子数组

做的时候没注意看题目,题目要求是和大于等于target的数组长度,我写成长度等于target的长度了,导致一直没通过,还找不到问题。。。。。。

1、我写的代码

用了两个指针s,f,当sum大于等于target时,只能向右移动慢指针,当sum小于target时,窗口需要增加元素,也就是需要向右移动快指针。(快指针应该始终在慢指针的右侧)

//和等于target的数组长度
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
            int len=Integer.MAX_VALUE;//用来记录最小长度
            int s=0;//慢指针
            int f=0;//快指针
            int sum=0;
            while(f<nums.length){
                    sum=sum+nums[f];
                    if(sum==target){
                        if(f-s+1<len){
//当和等于目标值时,并且数组的长度小于之前的最小长度时,更新最小长度。
                            len=f-s+1;
                        }
//当和等于目标值后,左指针需要往右移动,所以需要把当前的左指针指向的值减了,这样才能正确统计左指针到右指针的值的sum;
                        sum=sum-nums[s];
                        s++;f++;
                    }else{
                        if(sum<target){
                            f++;
                        }else{
                            sum=sum-nums[s];
                            if(s<f){//有可能数组每个元素都比target大
                            s++;
//这一步是因为,之前循环的时候会先加一个nums[f],而这时f没有更新,所以如果不减的话,sum就会继续加同一个nums[f]。
                            sum=sum-nums[f];
                            }else{
                            s++;
                            f++;
                            }
                        }
                    }
            }
        return len==Integer.MAX_VALUE?0:len;
    }
}
//和大于等于target的子数组,和上面的类似,把上面的稍微改一下就可以了。
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
                int s=0;
                int f=0;
                int sum=0;
                int len=Integer.MAX_VALUE;
                while(f<nums.length){
                    sum=sum+nums[f];
                    if(sum>=target){
                        if(f-s+1<len){
                            len=f-s+1;
                        }
                         sum=sum-nums[s];
                        if(s<f){
                            s++;
                            sum=sum-nums[f];
                        }else{
                            s++;f++;
                        }
                    }else{
                        f++;
                    }

                }
                return len==Integer.MAX_VALUE?0:len;

    }
}

写的时候有很多边界条件没有考虑清楚,边改边通过了。。。。。

//看了一下代码随想录的题解,发现可以用一个while循环代替if语句,
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
            int j=0,i=0;
            int sum=0;
            int len=Integer.MAX_VALUE;
            while(j<nums.length){
                sum+=nums[j];
                while(sum>=target){
                    if(j-i+1<len){
                        len=j-i+1;
                    }sum=sum-nums[i];
                    i++;
                }
            j++;
            }
            return len==Integer.MAX_VALUE?0:len;
    }
}

class Solution {
    public int totalFruit(int[] fruits) {
            //map表示水果的种类,个数
            //while (map里的种类少于2||当前水果存在map里){把当前种类的水果加进去,r++;}
            //否则:
            //统计map里的水果情况,判断是否更新最大数目,然后清空map,从r-1开始,往前找,找到第一个不等于fruits[r-1]种类的水果,更新map,把fruits[r-1]类的水果加入map。
            //最后返回的时候要加一个判断,有可能总共只有类或者两类水果,就执行不到上面的更新最大数目的代码
            
            Map<Integer,Integer> map=new HashMap<>();
            int l=0,r=0;
            int len=0;
            while(r<fruits.length){
                if(map.size()<2){
                    if(!map.containsKey(fruits[r])){
                        map.put(fruits[r],1);

                    }else{
                        map.put(fruits[r],map.get(fruits[r])+1);
                    }
                r++;
            }else{
               if(map.containsKey(fruits[r])){
                        map.put(fruits[r],map.get(fruits[r])+1);
                        r++;

                    }else
                    {
                        int temp=0;
                        for(Integer i:map.values()){
                            temp+=i;
                        }
                        if(temp>len){
                            len=temp;
                        }
                        map.clear();
                        l=r-1;
                        int temp1=fruits[l];
                        while(fruits[l]==temp1){
                            l--;
                        }
                        map.put(temp1,r-l-1);
                    }
            }
            }
            int temp=0;
            for(Integer i:map.values()){
                temp+=i;
            }
            if(temp>len){
                len=temp;
            }
            return len;
    
}
}

59.螺旋矩阵

题目链接: https://leetcode.cn/problems/spiral-matrix-ii/description/

  • 今天比较忙,先更新一下自己没看题解前写的弱智代码。。。。。
class Solution {
    public int[][] generateMatrix(int n) {

    //先往右走,等到了最右边,或者右边已经被填充了,就往下走;
    //往下走,如果下面到头了,或者下面已经被填充,就往左走;
    //定义0,1,2,3;
    //0是右,1是下,2是左,3是上;
    int index=2;
    int dir=0;
    int row=0;
    int col=0;
    int[][] arr=new int[n][n];
    for(int i=0;i<arr.length;i++){
        for(int j=0;j<arr[i].length;j++){
            arr[i][j]=-1;
        }
    }
    arr[0][0]=1;
    while(index<=n*n){
        if(dir==0){
            if(col<n-1&&arr[row][col+1]==-1){
                arr[row][col+1]=index;
                col++;
            }else{
                dir=1;
                arr[row+1][col]=index;
                row++;
            }

        }else if(dir==1){
                        if(row<n-1&&arr[row+1][col]==-1){
                arr[row+1][col]=index;
                row++;

            }else{
                dir=2;
                arr[row][col-1]=index;
                col--;
            }

        }else if(dir==2){
                        if(col>0&&arr[row][col-1]==-1){
                arr[row][col-1]=index;
col--;
            }else{
                dir=3;
                arr[row-1][col]=index;
                row--;
            }

        }else if(dir==3){

            if(row>0&&arr[row-1][col]==-1){
                arr[row-1][col]=index;
                row--;

            }else{
                dir=0;
                arr[row][col+1]=index;
                col++;
            }
        }
                index++;
    }


    return arr;

    }
}

每次写着写着就混乱了 QAQ。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值