算法学习|Day2数组 滑动窗口 螺旋矩阵

算法学习|Day2数组 滑动窗口 螺旋矩阵

今日任务:

数组理论基础,977有序数组的平方. 209长度最小的子数组,59.螺旋矩阵Ⅱ

LeetCode 977 有序数组的平方

977-有序数组的平方

解法一: 直接全平方,再排序 (Array.sort(nums))

class Solution {
    public int[] sortedSquares(int[] nums) {
        for(int i=0;i<nums.length;i++) nums[i]*=nums[i];
        Arrays.sort(nums);//java自带排序
        return nums;
    }
}

解法二: 双指针(左右指针)

比较左右大小,按顺序放入结果数组中(必须开辟新数组空间)

class Solution {
    public int[] sortedSquares(int[] nums) {
        int left=0,right=nums.length-1;
        int[] result = new int[nums.length];
        int index=result.length-1;
        while(left<=right){
            if(nums[left] * nums[left]>nums[right] * nums[right]){
                result[index--] = nums[left]*nums[left];
                left++;
            }
            else{
                result[index--] = nums[right]*nums[right];
                right--;
            }
        }
        return result;
    }
}

LeetCode 209 长度最小的子数组

滑动窗口(双指针法)

先在右边进窗口,窗口中和够大了之后,从左边出窗口,保存符合的窗口的最小长度

  • 使用快慢指针包住一个区间,根据其中的sum与target比较
  • 符合条件就比较最小长度并保存
  • 整个过程走完,最终返回最小长度即可

通过不断调整快慢指针的位置,从而得到不同的子序列,子序列中找到最优解

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int left=0;
        int sum=0;
        int result=Integer.MAX_VALUE;
        for(int right=0;right<nums.length;right++){
            sum+=nums[right];
            while(sum>=target){
                result=Math.min(result,right-left+1);
                sum-=nums[left++];
            }
        }
        return result==Integer.MAX_VALUE?0:result;
    }
}

LeetCode 59 螺旋矩阵Ⅱ

处理边界问题是难点

边界处理规则上保持一致,比如都是左闭右开区间

  • 只需要一圈一圈处理
  • 下一圈就更新起始位置
  • 注意处理的层数为n/2,如果n为奇数,则需要再给中心位置赋值
class Solution {
    public int[][] generateMatrix(int n) {
        int loop=0;
        int[][] res=new int[n][n];
        int start=0;//循环开始点(start,start)
        int count=1;//填充数字
        int i,j;
        while(loop++<(n/2)){
            for(j=start;j<n-loop;j++) res[start][j]=count++;
            for(i=start;i<n-loop;i++) res[i][j]=count++;
            for(;j>=loop;j--) res[i][j]=count++;
            for(;i>=loop;i--) res[i][j]=count++;
            start++;
        }
        if(n%2==1){
            res[start][start]=count;
        }
        return res;
    }
}

数组章节总结

数组理论基础

  • 数组是存放在连续内存空间的相同数据类型的集合
  • 数组下标从0开始,内存地址连续
  • 增删操作要移动其他元素
  • 多维数组同样是连续地址

数组题型常用思想

  • 二分法

  • 左闭右开

  • 左闭右闭

  • 循环不变量/一致原则

双指针法

  • 通过两个指针在一个for循环完成两个for的工作
  • 快慢指针
  • 左右指针
  • 因题目情况而定采用不同的双指针

滑动窗口法

  • 实质还是快慢指针,指针不回头,不停移动序列位置区间,更新结果集
  • 滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)的暴力解法降为O(n)

模拟行为

  • 根据题意模拟行为
  • 关键在于边界条件的处理
  • 循环不变量原则,边界处理方式要保持一致性

你可能感兴趣的:(算法每日学习,算法,学习,leetcode)