首页 > 编程语言 >代码随想录算法训练营第一天 | 209. 长度最小的子数组 59. 螺旋矩阵 58. 区间和 Java实现

代码随想录算法训练营第一天 | 209. 长度最小的子数组 59. 螺旋矩阵 58. 区间和 Java实现

时间:2024-09-20 21:55:39浏览次数:16  
标签:right 59 58 int sum rtn 随想录 ++ 数组

209. 长度最小的子数组

题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/description/

解题思路

思路1:暴力解法

通过两个for循环,找出所有的可能的区间,并比较出最小区间

思路2:滑动窗口

因为需要找出的是连续的一个子数组,所以可以模拟一个从左到右滑动的一个框(也可以看成是一个区间),框内是一个子数组,如果子数组的值大于等于target,且框的长度最小,则这个框里面的元素,就是目标子数组。

代码实现1:

        public static int minSubArrayLen(int target, int[] nums) {
        // 使用一个for循环,找出最小区间
        int sum = 0;
        int left = 0;
        int rtn = Integer.MAX_VALUE; // 返回的最小区间长度
        for (int right=0; right < nums.length; right++) {
            // 滑动块向右扩展
            sum += nums[right];
            // 判断滑动框内是否有更小的,满足条件的区间
            while(sum >= target) {
                rtn = Math.min(rtn, right - left + 1);
                sum -= nums[left++];
            }
        }
        return rtn == Integer.MAX_VALUE ? 0 : rtn;
    }

代码实现2:

public int minSubArrayLen(int target, int[] nums) {
        // 定义一个滑动框
        int sum = 0; // 滑动框内子数组的和
        int rtn = 0; // 最小的子数组长度
        int left = 0;  // 表示滑动框最左的下标
        int right = 0; // 表示滑动框最右的下标
        while(true) {
            // 如果框内的和小于target,则需要向右扩展
            if (sum < target) {
                // 判断条件,如果数组遍历结束,则跳出循环
                if (right >= nums.length) {
                    break;
                }
                sum += nums[right++];
                continue;
            }
            // 总和大于等于target时,判断最小长度
            // 不需要加一,因为向右扩展时,右指针已经跳到下一个元素了
            rtn = rtn == 0 ? right - left: Math.min(rtn, right - left);
            // 总和大于target,则需要缩小滑动框
            sum -= nums[left++];
        }
        return rtn;
    }

59. 螺旋矩阵

题目链接:https://leetcode.cn/problems/spiral-matrix-ii/description/

解题思路

这道题没有简便方法,只有模拟数字填充的过程。

思路1:贪吃蛇法

螺旋矩阵就像贪吃蛇的房间,遇到墙就得换个方向。从0,0位置开始,向右开始填充,如果右边碰到墙了,则向下填充,向下碰到墙了,向左填充,向左碰到墙了,在向上;以此类推,这里的碰到墙就是满足下面一个条件:
1、坐标等于n-1
2、坐标等于0
3、下一个空格已有值了(Java初始化的数组默认填充的是0)
代码如下:

  public static int[][] generateMatrix0(int n) {
        int square = n * n;
        // 创建一个矩阵
        int[][] rtn = new int[n][n];
        // 设置一个方向 0:右,1:下,2:左,3:上
        int direction = 0;
        // 设置当前数字所在坐标
        int x = 0; // 横坐标
        int y = 0; // 纵坐标
        for (int i = 1; i <= square; i++) {
            rtn[y][x] = i;
            // 判断下一步怎么走
            if (direction == 0) {
                // 向右,如果到头了,则转向下
                if (x + 1 == n || rtn[y][x+1] != 0) {
                    direction = 1;
                    y++;
                } else {
                    x++;
                }
            } else if (direction == 1) {
                // 向下,如果到头了,则转向左
                if (y + 1 == n || rtn[y+1][x] != 0) {
                    direction = 2;
                    x--;
                } else {
                    y++;
                }
            } else if (direction == 2) {
                // 向左到头了,则向上
                if (x == 0 || rtn[y][x-1] != 0) {
                    direction = 3;
                    y--;
                } else {
                    x--;
                }
            } else {
                // 向上,到头了则向右
                if (rtn[y-1][x] != 0) {
                    direction = 0;
                    x++;
                } else {
                    y--;
                }
            }
        }
        return rtn;
    }

思路2:画圈法

螺旋矩阵可以看成画圈,先把外面的圈填充完,再填充里面的。要注意的是,行和列的空格数量是一致的,术语话就是要坚持循环不变量原则,处理每一行或每一列,都是左闭右开区间
示例图如下:
在这里插入图片描述
代码实现:

 public static int[][] generateMatrix(int n) {
        int[][] rtn = new int[n][n];
        int loop = 1; // 记录当前是第几圈
        int indexX = 0, indexY = 0; // 记录下一个圈的起始坐标
        int count = 1; // 记录矩阵值
        int i=0,j=0; // 记录当前放入值的坐标
        // 每行都是左闭右开区间
        // n/2 是多少就可以有几个圈
        while(loop <= n / 2) {
            // 每次都是从起始位置开始
            i = indexX;
            j = indexY;
            // 处理顶行
            for (; i < n - loop; i++) {
                rtn[j][i] = count++;
            }

            // 处理最右列
            for (; j<n-loop; j++) {
                rtn[j][i] = count++;
            }

            // 处理下行
            for (;i>indexX;i--) {
                rtn[j][i] = count++;
            }

            // 处理左列
            for (;j>indexY;j--) {
                rtn[j][i] = count++;
            }

            // 进入下一圈
            loop++;
            indexX++;
            indexY++;
        }
        // 如果是奇数,最后的一个位置在中心,需要特殊处理
        if (n % 2 == 1) {
            rtn[indexY][indexX] = count;
        }
        return rtn;
    }

58. 区间和

题目链接:https://kamacoder.com/problempage.php?pid=1070

解题思路

前缀和

题目要求是获取一个数组,并返回指定区间数组元素的合。那用一个数组 sums 来存储前缀和,sums[i] 的值就表示从 0~i 的合,获取指定区间的合只需要用终止节点的前缀合减去起始节点前一个节点的合就可以了。
小提醒,题目内提交的Java代码,类名称必须是Main

代码实现:


import java.util.Scanner;

/**
 * 区间和
 */
public class Main {
     public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 获取n
        int n = scanner.nextInt();
        // 用于存储区间和
        int[] sums = new int[n];
        // 从控制器输入数据,并存储到区间和内
        int sum = 0;
        for (int i=0; i<n; i++) {
            int num = scanner.nextInt();
            sum += num;
            sums[i] = sum;
        }
        // 获取区间,并输出和
        while(scanner.hasNextInt()) {
            int start = scanner.nextInt();
            int end = scanner.nextInt();
            if (start == 0) {
                System.out.println(sums[end]);
            } else {
                System.out.println(sums[end] - sums[start-1]);
            }
        }

        // 记得关闭输入
        scanner.close();
    }

}

标签:right,59,58,int,sum,rtn,随想录,++,数组
From: https://blog.csdn.net/weixin_43872547/article/details/142344713

相关文章

  • 代码随想录算法 - 回溯3
    明天开始建模比赛,没时间写思路了题目193.复原IP地址有效IP地址正好由四个整数(每个整数位于0到255之间组成,且不能含有前导0),整数之间用'.'分隔。例如:"0.1.2.201"和"192.168.1.1"是有效IP地址,但是"0.011.255.245"、"192.168.1.312"和"[email protected]"是无......
  • 代码随想录算法训练营,9月20日 | 93.复原IP地址,78.子集,90.子集II
    93.复原IP地址题目链接:93.复原IP地址文档讲解︰代码随想录(programmercarl.com)视频讲解︰复原IP地址日期:2024-09-20Java代码如下:classSolution{List<String>res=newArrayList<>();privatevoidbackTracking(Strings,intstartIndex,intpointNum){......
  • 58. 最后一个单词的长度
    给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。 示例1:输入:s="HelloWorld"输出:5解释:最后一个单词是“World”,长度为5。示例2:输入:s="flymetoth......
  • 代码随想录训练营第38天|string虚拟头
    322.零钱兑换classSolution{public:intcoinChange(vector<int>&coins,intamount){vector<int>dp(amount+1,INT_MAX);dp[0]=0;for(auto&coin:coins){for(inti=1;i<=amount;i++){......
  • 闯关leetcode——58. Length of Last Word
    大纲题目地址内容解题代码地址题目地址https://leetcode.com/problems/length-of-last-word/description/内容Givenastringsconsistingofwordsandspaces,returnthelengthofthelastwordinthestring.Awordisamaximalsubstringconsisting......
  • 基于RK3588,AI边缘模块,单片6TOPS,可集群堆叠,Mixtile Blade 3
    MixtileBlade3 是一款经济实惠、节能的SBC,围绕下一代8纳米瑞芯微RK3588处理器构建。它非常适合快速开发、AI应用程序原型设计和边缘计算,允许您集群多个MixtileBlade3SBC以扩展您的部署。硬件布局正反面开箱即用的MixtileBlade3是一款可堆叠计算机,带有板载......
  • 158.337 Queries (SQL/LINQ), Triggers
    158.337GroupProjectInstructions:PartB(Coursemark- 17.5%)Youwillcontinuetoworkingroups*forthisassignment.Youdonotneedto registeragain but in case you change your group membership please let us know via emailing Indu (i......
  • 代码随想录算法训练营第十六天 | Javascript | 力扣Leetcode | 回溯 | 77. 组合、216.
    目录前言简介题目链接:77.组合题目链接:216.组合总和3题目链接:17.电话号码的字母组合前言踏平坎坷成大道,斗罢艰险又出发!自律的尽头是自控,自控的尽头是硬控。愿道友们披荆斩棘,终能得偿所愿。简介本人是小几年经验的前端开发,算法基础只有力扣几十道题,非常薄......
  • 代码随想录算法训练营第十五天 | Javascript | 继续二叉树的一天 | 力扣Leetcode | 补
    目录前言简介题目链接:501.二叉搜索树中的众数题目链接:236.二叉树的最近公共祖先题目链接:235.二叉搜索树的最近公共祖先前言踏平坎坷成大道,斗罢艰险又出发!自律的尽头是自控,自控的尽头是硬控。愿道友们披荆斩棘,终能得偿所愿。简介本人是小几年经验的前端开发,......
  • 代码随想录 -- 二叉树 -- 把二叉搜索树转换为累加树
    538.把二叉搜索树转换为累加树-力扣(LeetCode)思路:定义pre变量用来记录当前节点的前一个节点(右中左顺序遍历)的值。递归出口:当root为空时,return。单层递归逻辑:(右中左)右:self.tra(root.right)中:令root的值为它本身加上pre,更新pre为当前root的值;左:self.tra(root.left)class......