代码随想录day2

题目列表

  • 209长度最小的子数组(LeetCode)
  • 27移除元素(LeetCode)
  • 58.区间和(卡码网)

解题过程

209长度最小的子数组

题目描述

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

解题思路

滑动窗口

注意事项

1. 滑动窗口是什么

满足其和 ≥ target 的长度最小的连续子数组。

2. 窗口如何滑动

如果当前窗口的值大于等于target了,窗口就要向前移动了。
窗口起始位置总是在窗口大于或等于target时向后移动。
窗口结束位置会一直移动到数组末尾才算结束,但期间会“暂停下来”,等待窗口缩小,直到窗口小于目标值了,再继续移动。这个“暂停”是为了保证子数组长度最小。

3. 时间复杂度为O(n),因为:

● 外层 for 循环对每个元素遍历一次,时间复杂度为 O(n)。
● 内层 while 循环虽然在最坏情况下看起来像是嵌套循环,但由于每个元素最多只被从窗口中移除一次(即 left 指针最多移动 n 次),整体的操作次数仍然是线性的
● 每个元素都是被操作两次,所以时间复杂度是 2 × n

代码展示

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int result = Integer.MAX_VALUE;
        int left = 0;
        int sum = 0;
        for(int right = 0; right < nums.length; right++){
            sum += nums[right];
            while(sum >= target){
                int subL = right - left + 1;
                result = Math.min(result , subL);
                //起始位置向后移动
                sum -= nums[left];
                left++;
            }
        }
        if(result != Integer.MAX_VALUE){
            return result;
        }
        return 0;
    }
}

59.螺旋矩阵2

题目描述

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例 1:
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入:n = 1
输出:[[1]]

解题思路

逐圈填充。

注意事项

1.循环不变量与边界

每一圈的四个边都按照左闭右开来做,注意循环条件的关联。

2.要预先定义许多变量,搞清楚它们的作用

首先rowNumberOrigin和columnNumberOrigin的作用是在循环中自增,表示每一圈行和列的起始点,这样循环用的i,j就更清晰,不光是起始点在增加,它的结束点也在变小,所以使用offset自增来让(n-offset)变小。

3. 注意n是奇数还是偶数

如果是奇数,最后一圈就只剩一个元素,直接填充即可。

代码展示

class Solution {
    public int[][] generateMatrix(int n) {

        int [][] nums = new int [n][n];
        int columnNumberOrigin = 0;
        int rowNumberOrigin = 0;
        int offset = 1;
        int count = 1;
        int loop = 1;
        int i, j;

        while(loop <= n/2){

            //在顶行填充,行数不变,列数遍历到n-offset - 1,左闭右开
            for(j = columnNumberOrigin; j < n - offset; j++){
                nums[rowNumberOrigin][j] = count++;
            }
             //在右列填充,列数不变(顶行遍历结束位置j),行数遍历到n-offset - 1,左闭右开
            for(i = rowNumberOrigin; i < n - offset; i++){
                nums[i][j] = count++;
            }
             //在底行填充,行数不变,列数遍历到列数起始值columnNumberOrigin,左闭右开
            for( ; j > columnNumberOrigin; j--){
                nums[i][j] = count++;
            }
             //在左列填充,列数不变,行数遍历到行数起始位置rowNumberOrigin,左闭右开
            for( ; i > rowNumberOrigin; i--){
                nums[i][j] = count++;
            }
            //一圈结束,缩小
            loop++;
            columnNumberOrigin++;
            rowNumberOrigin++;
            offset++;

        }
        if(n%2 != 0){
            nums[rowNumberOrigin][columnNumberOrigin] = count;
        }

        return nums;

    }

}

58. 区间和(第九期模拟笔试)

题目描述

给定一个整数数组 Array,请计算该数组在每个指定区间内元素的总和。

解题思路

前缀和

注意事项

时间卡的比较死,要按照最高效的来。

代码展示

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] arr = new int[n];
        int[] p = new int[n];
        int current = 0;
        for(int i = 0; i < n; i++){
            arr[i] = scanner.nextInt();
            current += arr[i];
            p[i] = current;
        }
        while(scanner.hasNextInt()){
            int left = scanner.nextInt();
            int right = scanner.nextInt();
            int sum;
            if(left == 0){
               sum = p[right];
            }else{
               sum = p[right] - p[left-1];
            }
             System.out.println(sum);
        }
    }
}

参考资料

代码随想录

posted @ 2025-04-24 15:10  cbdsszycfs  阅读(548)  评论(0)    收藏  举报