算法训练-Day2| 977.有序数组的平方、 209.长度最小的子数组、 59.螺旋矩阵II

LeeCode  977.有序数组的平方

①暴力解法

public int[] sortedSquares(int[] nums) {
        //暴力解法
        for (int i = 0; i < nums.length; i++)
            nums[i] = nums[i]*nums[i];

        int temp;
        //选择排序
        for (int i = 0; i < nums.length; i++) {
            int min = i;
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[j] < nums[min]) {
                   min = j;
                }
            }
            temp = nums[i];
            nums[i] = nums[min];
            nums[min] = temp;
        }
        return nums;
    }

②双指针法

        这题考查了双指针法的灵活应用,,根据题意可知从小到大排序,且存在负数,平方后两边大,逐步向中间减小,因此可以用空间换时间,创建一个新数组,依次从两端往中间比较大小后放入新数组中。

 public int[] sortedSquares(int[] nums) {
        // 双指针法(循环不变量)    
        int [] result = new int [nums.length];
        int left = 0;
        int right = nums.length-1;
        // 注意:下标要为最后一个元素的数值,而不是数组长度
        int index = nums.length-1;  


        while(left <= right){
            if(nums[left]*nums[left] < nums[right]*nums[right]){
                result[index--] =  nums[right]*nums[right];
                right--;
            }else{
                result[index--] = ums[left]*nums[left];
                left++;
            }
        }

        return result;
    }
LeeCode  209.长度最小的子数组

①暴力解法(时间复杂度太大,会超出时间限制)

 public int minSubArrayLen(int target, int[] nums) {
        int result = Integer.MAX_VALUE; //初值要定为int型变量的最大值
        int sum = 0;  //数值之和
        int subLength = 0;   //记录子数组的长度
        for(int i = 0;i < nums.length;i++){
            sum = 0;
            for(int j = i;j < nums.length;j++){
                sum += nums[j];
                if(sum >= target){
                    subLength = j-i+1;
                    if(subLength < result)
                        result = subLength;
                        
 //在得到之和大于target的长度之和就要break退出j的for循环,因为此时是起始位置为i使得到的最短子数组
                    break; 
                }
            }
        }

        if(result == Integer.MAX_VALUE)
            return 0;  //result仍为int型变量最大值表明所有数值之和都小于target
        else
            return result;
    }

②滑动窗口(双指针法的一种)

        关于滑动窗口问题,要明确①窗口内是什么  ②窗口的初始位置如何移动 ③窗口的终止位置如何移动。这三个问题要先搞清楚。

        在本题中:

        窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。

        窗口的起始位置如何移动:如果当前窗口的值大于等于s了,窗口就要向前移动了(也就是该缩小了)。

        窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

 public int minSubArrayLen(int target, int[] nums) {
        // 技巧:取int最大值,在下面每次取得最小值,即最小长度
        int result = Integer.MAX_VALUE;
        int sum = 0;  //数值之和
        int left = 0;

        for(int right = 0;right < nums.length;right++){
            sum += nums[right];
            while(sum >= target){  //不断更新左指针
                result = Math.min(result,right-left+1);
                sum -= nums[left];
                left++;
            }
        }
        return result == Integer.MAX_VALUE? 0:result;
    }
LeeCode59.螺旋矩阵II(本题理解的还不够深,后面要再回顾一下)

        碰到这类题目时要遵循循环不变量原则,就是在循环时,要有一定的顺序和规律去遍历。在本题中要注意(top <= bottom && left <= right),这个条件要一直成立,而缩小完上边界和右边界后top和right的值都有更改,因此在缩小完上边界和右边界要再判断一下该条件是否成立。

 public int[][] generateMatrix(int n) {
            int [][] matrix = new int[n][n];
            int top = 0,bottom = n-1;
            int left = 0,right = n-1;
            int count = 1;

            //若条件为,则n为奇数时,矩阵中心数字无法再迭代过程中被填充
            while(top <= bottom && left <= right){
                //从左到右,相当于缩小上边界,左边界小于等于有边界
                for(int i = left;i <=right;i++)
                    matrix[top][i] = count++;
                    
                top++; //缩小上边界

                //从上到下,相当于缩小右边界,上边界小于等于下边界
                for(int i = top;i <= bottom;i++)
                    matrix[i][right] = count++;

                right--; //缩小右边界

                if(top <= bottom && left <= right){
                     //从右到左,相当于缩小下边界,右边界大于等于左边界,且下边界大于等于上边界
                    for(int i = right;i >= left;i--)
                        matrix[bottom][i] = count++;
                    bottom--;   //相当于缩小下边界

                    //从下到上,相当于缩小左边界大于等于有边界,且左边界小于等于右边界
                    for(int i = bottom;i >= top;i--)
                        matrix[i][left] = count++;
                    left++;
                }                
            }
            return matrix;

    }

  • 18
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值