数组部分:双指针的另外一个名字“滑动窗口”

代码随想录算法训练营第2天 | 数组部分: 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

数组部分

977.有序数组的平方

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

先将数组中的负数转换成正数进行排序,然受对排序之后的数组进行平方
暴力的解法可以成功解决

public int[] sortedSquares(int[] nums) {
      for(int i=0;i<nums.length;i++){
          if(nums[i]<0){
              nums[i]=-nums[i];
          }
      }
      Arrays.sort(nums);
      for(int i=0;i<nums.length;i++){
          nums[i]= nums[i]*nums[i];
      }
      return nums;
    }

方法2 双指针的解法

209.长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

思路:一个变量用于更新最小长度 使用快慢指针来进行解决,快慢指针之间的区间就是连续数组的长度 ,看了答案之后,这种描述的话应该叫做滑动窗口
问题:如何解决慢指针的更新问题
最初的想法:慢指针先保持不移动,快指针向前,和大于value时停止,此时更新慢指针,目的是为了计算出最小的长度,更新了长度之后,此时和小于value,快指针继续向前,重复之前的操作就可以
写代码遇到的问题:如何进行最小长度的更新
常量:Integer.MAX_VALUE;正数的最大值

public int minSubArrayLen(int target, int[] nums) {
      int slow=0,fast=0,sum=0,minL=Integer.MAX_VALUE,numsL=0;
        for(int i=0;i<nums.length;i++){
         sum +=nums[i];//这边的代码是为了解决数组的所有元素和仍然小于target的情况
        }
        if(sum<target){
            return 0;
        }
        sum=0;
        //之前使用while来完成fast的遍历,会产生一个情况,即最后一个位置的fast
        //不能被加入到和里面 
        for(;fast<nums.length;fast++){
                if(sum<target){
                    sum +=nums[fast];
                    numsL++;
                }
                //这边使用while是为了保证 slow可以在满足条件的情况下,不断的向前移动
                while(slow<=fast&&sum>=target){
                    minL=Math.min(minL,numsL);//这边是最小值的更新
                    numsL--;
                    sum -=nums[slow];
                    slow++;
                }
        }
        return minL;
    }

59. 螺旋矩阵 II

给你一个正整数 n ,生成一个包含 1 到 n的平方所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

这边能想到的思路是:按照顺时针的顺序向二维数组里面添加元素,定义四个边界,上下左右,但是感觉具体的代码写的很困难,不知道到底该怎么描述
补充二维数组的概念

int[][] a=new int[m][n];//表示m行n列

写出来了!!!!!!!!!!!!!!
while外层循环保证一共插入了n的平方个元素
内层for循环保证顺时针遍历元素
从左到右
从上到下
从右到左
从下到上

 public int[][] generateMatrix(int n) {
         int top=0,left=0,right=n-1,bottom=n-1;
        int[][] res=new int[n][n];
        int sum=1;
        while(sum<=n*n){
            for(int i=left;i<=right&&sum<=n*n;i++){
                res[top][i]=sum;
                sum++;
            }
            top++;
            for(int i=top;i<=bottom&&sum<=n*n;i++){
                res[i][right]=sum;
                sum++;
            }
            right--;
            for(int i=right;i>=left&&sum<=n*n;i--){
                res[bottom][i]=sum;
                sum++;
            }
            bottom--;
            for(int i=bottom;i>=top&&sum<=n*n;i--){
                res[i][left]=sum;
                sum++;
            }
            left++;
        }
        return res;
    }

今天事情有点多,等我明天看完总结再进行总结

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值