代码随想录训练Day2[数组02]

代码随想录训练Day2[数组02]

209.长度最小的子数组

滑动窗口:

思路: 子数组的长度会不断变更, 可能在中间,可能 在两边,也可能在中间,所以要是值一个值和每次产生的子数组长度作比较。依旧是两重循环,一重循环来遍历整个数组,第二重循环,来寻找字串的位置。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int result_length = Integer.MAX_VALUE;  // 设置数组的最大值,和子数组的大小做比较
        int sums = 0 ;
        int sun_length = 0;
        int  j = 0;                             // j 值 很关键 相当于后排的索引
        for (int i = 0; i < nums.length; i++) {     //我们先想第一次如何解, 再将 第一次中 的固定值 改为变量
            sums += nums[i];
            while (sums >= target) {
                sun_length = i - j + 1;  //yin
                result_length = Integer.min(result_length,sun_length);
                sums -= nums[j];
                j++;
            }
        }
        return result_length == Integer.MAX_VALUE ? 0 : result_length;
    }
}

59.螺旋矩阵II

首先我没搞懂要循环几次,也就是while() 中的条件,应该是n/2 , 但首先考虑到n 分奇偶,如果是奇数,就会留下中间的位置,在最后判断如果是奇数就对填充的数组单独的赋值,也就是nums[n/2,n/2] = n* n;

然后是区间,选用左闭右开 但记住右开 区间的值就是 n -offset,记住这里是下标,填充元素一行不变,一行++,

class Solution {
        public int[][] generateMatrix(int n) {
            int curr = 0;
            int cnt = 1;
            int startx = 0;
            int starty = 0;
            int i = 0, j = 0;
            int offset = 1;
            int[][] result = new int[n][n];
            while (curr <= n / 2) { //确定循环圈数 首先考虑到奇偶的 如果是奇数的话就将其放到最后填充
                //j 的开始一定是startx 计数 内圈的时候 起始值就不一样了 对应下面的startxy
                for (j = starty; j < n - offset; j++) {
                    result[startx][j] = cnt++;
                }
                
                for (i = startx; i < n - offset; i++) {
                    result[i][j] = cnt++;
                }

                for(; j > starty ; j--){
                    result[i][j] = cnt++;
                }

                for (; i > startx ; i--){
                    result[i][j] = cnt++;
                }
			
                offset ++;
                startx++;
                starty++;
                curr++;
            }
            //最后对奇偶进行判断
            if (n % 2 != 0){
                result[i][j]= n*n;
            }
            return result;
        }
    }
  1. 区间和(卡码网第九期模拟笔试)

好吧第一次接触ACM模式还是有点吃惊的,啥都没有全要自己写,我都忘记怎么写mian,这题正好熟悉一下。

前缀和:理解了不难,但第一次有点难想,还是想会用两个索引,从a 加到b ,实际做完,发现最后还有边界要考虑

要将a = 0单独考虑,这个区间是左包右包的所以要将a 的上一个值去掉

记住模板吧! 要不然遇到ACM 就gg

import java.util.*;
public class Main
{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] array = new int[n];
        int[] sumArry = new int[n];
        int sum = 0;        //用来解决数组越界问题 
        for(int i = 0 ; i < n ; i ++ ){
            array[i] = scanner.nextInt();
            //这里第一次如何处理 数组越界问题
            sum += array[i];
            sumArry[i] = sum;
        }
        
        int a ;
        int b ;
        while (scanner.hasNextInt()) {
            //这里注意数组从0 开始数 
 
            a = scanner.nextInt();
            b = scanner.nextInt();
            //界定一下边界条件 
            if( a == 0 ){
                sum = sumArry[b];
            }else{
                //区间是包含两边的 当输入的是1 就要将1 之前的值0 去掉
                sum = sumArry[b] - sumArry[a - 1];
            }
            System.out.println(sum);
        }
        scanner.close();
    }
}
  1. 开发商购买土地(第五期模拟笔试)

在一个城市区域内,被划分成了n * m个连续的区块,每个区块都拥有不同的权值,代表着其土地价值。目前,有两家开发公司,A 公司和 B 公司,希望购买这个城市区域的土地。

现在,需要将这个城市区域的所有区块分配给 A 公司和 B 公司。

然而,由于城市规划的限制,只允许将区域按横向或纵向划分成两个子区域,而且每个子区域都必须包含一个或多个区块。 为了确保公平竞争,你需要找到一种分配方式,使得 A 公司和 B 公司各自的子区域内的土地总价值之差最小。

注意:区块不可再分。

import java.util.*;

public class Main{
    public static void main(String[] args)
    {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int sum = 0;
        int[][] place = new int[n][m];
        for(int i = 0 ; i < n ; i++)
        {
            for(int j = 0 ; j < m ; j++){
                place[i][j] = scanner.nextInt();
                sum += place[i][j]; 
            }
        }

        //横向统计: 只有单列
        int[] sumy = new int[n];
        for(int i = 0 ; i < n ; i++){
            for(int j = 0 ;j < m; j++){
                sumy[i] += place[i][j];
            }
        }

        int[] sumx = new int[m];
        for(int j = 0 ;j < m ; j++){
            for(int i = 0 ; i < n ;i++){
                sumx[j] += place[i][j];
            }
        }
		//这里将行和列分开分别做了前缀
        int result = Integer.MAX_VALUE;
        int  y = 0;
        for(int i = 0; i < n ;i++){
            y += sumy[i];
            result = Math.min(result, Math.abs((sum - y) - y));
        }

        int x = 0;
        for(int j = 0; j < m ; j++){
            x += sumx[j];
            result = Math.min(result, Math.abs((sum - x) - x)); 
        }
        System.out.println(result);
        scanner.close();

    }
}
### 关于代码随想录 Day04 的学习资料与解析 #### 一、Day04 主要内容概述 代码随想录 Day04 的主要内容围绕 **二叉树的遍历** 展开,包括前序、中序和后序三种遍历方式。这些遍历可以通过递归实现,也可以通过栈的方式进行迭代实现[^1]。 #### 二、二叉树的遍历方法详解 ##### 1. 前序遍历(Pre-order Traversal) 前序遍历遵循访问顺序:根节点 -> 左子树 -> 右子树。以下是基于递归的实现: ```python def preorderTraversal(root): result = [] def traversal(node): if not node: return result.append(node.val) # 访问根节点 traversal(node.left) # 遍历左子树 traversal(node.right) # 遍历右子树 traversal(root) return result ``` 对于迭代版本,则可以利用显式的栈来模拟递归过程: ```python def preorderTraversal_iterative(root): stack, result = [], [] current = root while stack or current: while current: result.append(current.val) # 访问当前节点 stack.append(current) # 将当前节点压入栈 current = current.left # 转向左子树 current = stack.pop() # 弹出栈顶元素 current = current.right # 转向右子树 return result ``` ##### 2. 中序遍历(In-order Traversal) 中序遍历遵循访问顺序:左子树 -> 根节点 -> 右子树。递归实现如下: ```python def inorderTraversal(root): result = [] def traversal(node): if not node: return traversal(node.left) # 遍历左子树 result.append(node.val) # 访问根节点 traversal(node.right) # 遍历右子树 traversal(root) return result ``` 迭代版本同样依赖栈结构: ```python def inorderTraversal_iterative(root): stack, result = [], [] current = root while stack or current: while current: stack.append(current) # 当前节点压入栈 current = current.left # 转向左子树 current = stack.pop() # 弹出栈顶元素 result.append(current.val) # 访问当前节点 current = current.right # 转向右子树 return result ``` ##### 3. 后序遍历(Post-order Traversal) 后序遍历遵循访问顺序:左子树 -> 右子树 -> 根节点。递归实现较为直观: ```python def postorderTraversal(root): result = [] def traversal(node): if not node: return traversal(node.left) # 遍历左子树 traversal(node.right) # 遍历右子树 result.append(node.val) # 访问根节点 traversal(root) return result ``` 而迭代版本则稍复杂一些,通常采用双栈法或标记法完成: ```python def postorderTraversal_iterative(root): if not root: return [] stack, result = [root], [] while stack: current = stack.pop() result.insert(0, current.val) # 插入到结果列表头部 if current.left: stack.append(current.left) # 先压左子树 if current.right: stack.append(current.right) # 再压右子树 return result ``` #### 三、补充知识点 除了上述基本的二叉树遍历外,Day04 还可能涉及其他相关内容,例如卡特兰数的应用场景以及组合问题的基础模板[^2][^4]。如果遇到具体题目,可以根据实际需求调用相应算法工具。 --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值