代码随想录-数组2

977.有序数组的平方

力扣题目链接

基本思路

  1. 暴力解法,先全部平方,然后排序
  2. 双指针法,由于原本数组是有序的,从负数到正数,平方之后最大数只会出现在两端的位置。考虑设置一个新数组存放排序后的元素,利用相向指针判断选择要把哪个元素先放入新数组。

暴力排序

class Solution {
    public int[] sortedSquares(int[] nums) {
        //暴力解法
        for(int i = 0; i < nums.length; i++){
            nums[i] = nums[i] * nums[i];
        }
        Arrays.sort(nums);
        return nums;
    }
}
  • 时间复杂度:O(n + nlogn) == O(nlogn)
  • 空间复杂度:O(1)

双指针

class Solution {
    public int[] sortedSquares(int[] nums) {
        int n = nums.length;
        int left = 0;
        int right = n - 1;
        int[] arr = new int[n];
        int index = n - 1;
        while(left <= right){  //需要加上等于号,最后一个数的情况必定是,两个指针相遇
            if(nums[left]*nums[left] < nums[right]*nums[right]){
                arr[index--] = nums[right]*nums[right];
                right--;
            }else{
                arr[index--] = nums[left]*nums[left];
                left++;
            }
        }
        return arr;
    }
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

注意点

  1. Java数组排序:
    1. Arrays.sort(arr):升序
    2. javaArrays.sort(arr, Collections.reverseOrder()):降序,数组需要是引用类型
    3. Arrays.sort(int[] a, int fromIndex, int toIndex):对数组部分排序,也就是对数组a的下标从fromIndex到toIndex-1的元素排序,注意:下标为toIndex的元素不参与排序
    4. 实现Comparator接口的覆写compare()方法;
    5. 可参考:Java-Arrays.sort()详解
  2. Java中创建有n个元素的数组方法:int[] arr = new int[n]

209.长度最小的子数组

力扣题目链接

基本思路

  1. 使用双指针构建一个滑动窗口
  2. 开始时右侧指针右移逐步扩大窗口,直到满足条件记录当前的窗口大小,左侧指针右移一位;
  3. 若此时仍满足条件,左侧指针继续右移,逐步缩小窗口,若这个右移过程中满足条件,则更新窗口大小。
  4. 若不满足条件,右侧指针右移,直到满足条件记录当前的窗口大小(第一步)

滑动窗口

class Solution {
    // 滑动窗口
    public int minSubArrayLen(int s, int[] nums) {
        int left = 0;
        int sum = 0;
        int result = Integer.MAX_VALUE;
        //两个循环,但是O(n)复杂度
        //找到一个区间后,先尝试缩小这个窗口,直到不满足条件
        for (int right = 0; right < nums.length; right++) {
            sum += nums[right];
            while (sum >= s) {
                result = Math.min(result, right - left + 1);
                if(result == 1) return result;//最小就是1
                sum -= nums[left++];
            }
        }
        return result == Integer.MAX_VALUE ? 0 : result;
    }
}
  • 时间复杂度:O(n)
    • 看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)
  • 空间复杂度:O(1)

注意点

  1. 不需要每次找到符合条件的窗口后,把右侧指针移到左侧重新累加。在每一步中,左指针的移动都是在右指针已经确定的位置基础上进行的,因此不存在遗漏的可能。
  2. 窗口的起始位置如何移动:如果当前窗口的值大于等于s了,窗口就要向前移动了(也就是该缩小了)。
  3. 窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

59.螺旋矩阵II

力扣题目链接

基本思路

  1. 模拟类型的题,先想清楚要怎么一步一步模拟。这里是要填充一个矩阵(二维数组),填充值为从1到n2,填充时,每一条边只不包括最后一个顶点元素,做到四边统一边界
    1. 上边,从左到右
    2. 右边,从上到下
    3. 下边,从右到左
    4. 左边,从下到上
    5. 每次更新完最外面的四条边后,访问的元素的下标要往内部偏移1步
  2. 使用循环模拟,每次填充四条边,一步一步往内,到最中心时,每一条边都向内进了n/2步,所以循环结束条件为while(loop <= n/2)
  3. 单独考虑奇数情况,最后中间剩一个数字,位置为mat[n/2][n/2],值为n2

方法代码

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] mat = new int[n][n];
        int count = 1;
        int offset = 0;
        int loop = 1;
        int i , j;
        while(loop <= n/2){
            for(j = offset; j < n-offset-1; j++){
                mat[offset][j] = count++;
            }
            for(i = offset; i < n-offset-1; i++){
                mat[i][n-offset-1] = count++;
            }
            for(j = n-offset-1; j > offset; j--){
                mat[n-offset-1][j] = count++;
            }
            for(i = n-offset-1; i > offset; i--){
                mat[i][offset] = count++;
            }
            offset++;
            loop++;
        }
        if(n%2 != 0){
            mat[n/2][n/2] = count;
        }
        return mat;
    }
}
  • 时间复杂度:O(n2)
  • 空间复杂度:O(1)

注意点

  1. 考虑边界条件,保证每条边处理的原则一致
posted @   xloading  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示
主题色彩