周赛328总结

周赛328总结

第三题思路正确,但是但是卡在了返回结果用了int变量…很是无语
二维前缀和二维差分get

数组元素和与数字和的绝对差【LC2535】

给你一个正整数数组 nums

  • 元素和nums 中的所有元素相加求和。
  • 数字和nums 中每一个元素的每一数位(重复数位需多次求和)相加求和。

返回 元素和数字和 的绝对差。
注意:两个整数 xy 的绝对差定义为 |x - y|

  • 思路:遍历数组中的元素,使用一个变量记录元素和减去数位和的差值
  • 实现
class Solution {
    public int differenceOfSum(int[] nums) {
        int res = 0;
        for (int num : nums){
            res += num;
            int x = num;
            while (x > 0){
                res -= x % 10;
                x /= 10;
            }
        }
        return res;

    }
}
  • 复杂度
    • 时间复杂度:O ( n l o g U ) O(nlogU)O (n l o gU ),U = m a x ( n u m s ) U=max(nums)U =ma x (n u m s )
    • 空间复杂度:O ( 1 ) O(1)O (1 )

子矩阵元素加 1【LC2536】

给你一个正整数 n ,表示最初有一个 n x n 、下标从 0 开始的整数矩阵 mat ,矩阵中填满了 0 。
另给你一个二维整数数组 query 。针对每个查询 query[i] = [row1i, col1i, row2i, col2i] ,请你执行下述操作:

  • 找出 左上角(row1i, col1i)右下角(row2i, col2i) 的子矩阵,将子矩阵中的 每个元素1 。也就是给所有满足 row1i <= x <="row2i</code"> &#x548C; <code>col1i <= y <="col2i</code"> &#x7684; <code>mat[x][y]</code> &#x52A0; <code>1</code> &#x3002;<!--=--></code><!--=-->

返回执行完所有操作后得到的矩阵 mat

暴力

java过了…

class Solution {
    public int[][] rangeAddQueries(int n, int[][] queries) {
        int[][] mat = new int[n][n];
        for (int[] query : queries){
            int row1 = query[0], col1 = query[1], row2 = query[2], col2 = query[3];
            for (int i = row1; i  row2; i++){
                for (int j = col1; j  col2; j++){
                    mat[i][j]++;
                }
            }
        }
        return mat;

    }
}
  • 复杂度
  • 时间复杂度:O ( n 2 ∗ q ) O(n^2*q)O (n 2 ∗q ),q q q为q u e r i e s queries q u er i es的长度
  • 空间复杂度:O ( 1 ) O(1)O (1 )

二维差分

前置知识:二维差分数组与二维前缀和数组

  • 思路:使用二维差分数组记录每个区域的变化量,然后通过二维前缀和数组求得每个位置的值
  • 实现
  • 二维差分数组 div中的每一个格子记录的是「以当前位置为区域的 左上角(区域右下角恒定为原数组的右下角)的值的 变化量」【应该不固定 可以倒转】
  • 二维差分数组的二维前缀和数组 sum,即差分数组 以当前位置为右下角,原数组的左上角为左上角的区域和
  • 因此,如果要求 ( x 1 , y 1 ) (x1, y1)(x 1 ,y 1 ) 作为左上角,( x 2 , y 2 ) (x2, y2)(x 2 ,y 2 ) 作为右下角的区域值增加x x x的时候,可以利用二维差分数组快速求解,此时相当于二维差分矩阵上对( x 1 , y 1 ) (x1,y1)(x 1 ,y 1 )增加x x x,对( x 2 + 1 , y 1 ) (x2+1,y1)(x 2 +1 ,y 1 )和( x 1 , y 2 + 1 ) (x1,y2+1)(x 1 ,y 2 +1 )减小x x x,再对重复区域( x 2 + 1 , y 2 + 1 ) (x2+1,y2+1)(x 2 +1 ,y 2 +1 )增加x x x
  • 要求得二维数组每个位置( x 1 , y 1 ) (x1,y1)(x 1 ,y 1 )的变化量,即求二维差分数组的二维前缀和数组 sum,即差分数组 以当前位置为右下角,原数组的左上角为左上角的区域和
    s u m [ i , j ] = s u m [ i − 1 ] [ j ] + s u m [ i ] [ j − 1 ] − s u m [ i − 1 ] [ j − 1 ] + d e v [ i ] [ j ] sum[i,j] = sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+dev[i][j]s u m [i ,j ]=s u m [i −1 ][j ]+s u m [i ][j −1 ]−s u m [i −1 ][j −1 ]+d e v [i ][j ]
    • 初始时div数组需要扩展边界,转化为 sum时需要处理0
class Solution {
    public int[][] rangeAddQueries(int n, int[][] queries) {
        int[][] div = new int[n + 1][n + 1];
        for (int[] q : queries){
            div[q[0]][q[1]]++;
            div[q[0]][q[3] + 1]--;
            div[q[2] + 1][q[1]]--;
            div[q[2] + 1][q[3] + 1]++;
        }
        int[][] sum = new int[n][n];
        for (int i = 0; i < n; i++){
            for (int j = 0; j < n; j++){
                sum[i][j] = div[i][j];
                if (i != 0) sum[i][j] += sum[i - 1][j];
                if (j != 0) sum[i][j] += sum[i][j - 1];
                if (i != 0 && j != 0) sum[i][j] -= sum[i - 1][j - 1];
            }
        }
        return sum;
    }
}
  * 复杂度
    - 时间复杂度:O ( n 2 + q ) O(n^2+q)O (n 2 +q ),q q q为q u e r i e s queries q u er i es的长度
    - 空间复杂度:O ( 1 ) O(1)O (1 )
+ div数组边界可以+2,方便处理0 d i v [ 1 : n ] [ 1 : n ] div[1:n][1:n]d i v [1 :n ][1 :n ]计算为二维前缀和数组,在赋值给结果集
class Solution {
    public int[][] rangeAddQueries(int n, int[][] queries) {
        int[][] div = new int[n + 2][n + 2];
        for (int[] q : queries){
            div[q[0] + 1][q[1] + 1]++;
            div[q[0] + 1][q[3] + 2]--;
            div[q[2] + 2][q[1] + 1]--;
            div[q[2] + 2][q[3] + 2]++;
        }
        int[][] sum = new int[n][n];
        for (int i = 1; i  n; i++){
            for (int j = 1; j  n; j++){
                sum[i - 1][j - 1] = (div[i][j] += div[i - 1][j] + div[i][j - 1] - div[i - 1][j - 1]);
            }
        }
        return sum;
    }
}
  • 拓展:子矩阵元素变化量不定

统计好子数组的数目【LC2537】

给你一个整数数组 nums 和一个整数 k ,请你返回 nums 子数组的数目。
一个子数组 arr 如果有 至少 k 对下标 (i, j) 满足 i < jarr[i] == arr[j] ,那么称它是一个 子数组。
子数组 是原数组中一段连续 非空 的元素序列。

  • 思路:使用哈希表 valToCount记录每个数字出现的次数,然后枚举子数组右端点 r,那么新增的对数为 valToCount.get(nums[r]),然后当总对数大于等于k时,将左端点 l移动到最远的位置,那么当右端点为 r时,合法的左端点为[ 0 , l ] [0,l][0 ,l ],对结果的贡献为l + 1 l+1 l +1。
  • 实现
class Solution {
    public long countGood(int[] nums, int k) {
        int n = nums.length;
        int pair = 0;
        long res = 0;
        Map<Integer,Integer> intToCount = new HashMap<>();
        int l = 0;
        for (int r = 0; r < n; r++){
            pair += intToCount.getOrDefault(nums[r], 0);
            intToCount.put(nums[r], intToCount.getOrDefault(nums[r], 0) + 1);

            while(pair - intToCount.get(nums[l]) + 1 >= k && l < n){
                intToCount.put(nums[l], intToCount.get(nums[l]) - 1);
                pair -= intToCount.get(nums[l]);
                l++;
            }
            if (pair >= k){
                res += l + 1;
            }
        }
        return res;
    }
}
  • 复杂度
    • 时间复杂度:O ( n ) O(n)O (n )
    • 空间复杂度:O ( 1 ) O(1)O (1 )

最大价值和与最小价值和的差值【LC2538】

给你一个 n 个节点的无向无根图,节点编号为 0n - 1 。给你一个整数 n 和一个长度为 n - 1 的二维整数数组 edges ,其中 edges[i] = [ai, bi] 表示树中节点 aibi 之间有一条边。
每个节点都有一个价值。给你一个整数数组 price ,其中 price[i] 是第 i 个节点的价值。
一条路径的 价值和 是这条路径上所有节点的价值之和。
你可以选择树中任意一个节点作为根节点 root 。选择 root 为根的 开销 是以 root 为起点的所有路径中, 价值和 最大的一条路径与最小的一条路径的差值。
请你返回所有节点作为根节点的选择中, 最大开销 为多少。

树形dp

  • 思路:
  • 由于价值都是正数,因此价值和最小的一条路径一定 只有一个点。那么,「价值和最大的一条路径与最小的一条路径的差值」等价于「去掉路径的一个端点」,因此问题可以转化为问题转换成 去掉一个叶子后的 最大路径和(这里的叶子严格来说是度为 1 的点,因为根的度数也可能是 1)。
  • 使用树形dp找到 去掉一个叶子后的 最大路径和:在树上做DFS,递归到最底层的叶子节点,再一层层返回当前带叶子的路径和」和「当前不带叶子的路径和」更新至根结点,对于根节点而言,答案的可能性有两种:
    • 前面最大带叶子的路径和 + 当前不带叶子的路径和;
    • 前面最大不带叶子的路径和 + 当前带叶子的路径和; 然后更新「最大带叶子的路径和」和「最大不带叶子的路径和」以及结果。
  • 实现
  • 使用邻接表存储二叉树
  • 然后使用树形dp将结果一层一层返回至根节点,由于每个节点只遍历一次,因此不需要写成记忆化搜索的形式,当遇到更大的值时,更新结果
class Solution {
    private List<Integer>[] g;
    private int[] price;
    private long ans;

    public long maxOutput(int n, int[][] edges, int[] price) {
        this.price = price;
        g = new ArrayList[n];
        Arrays.setAll(g, e -> new ArrayList<>());
        for (var e : edges) {
            int x = e[0], y = e[1];
            g[x].add(y);
            g[y].add(x);
        }
        dfs(0, -1);
        return ans;
    }

    private long[] dfs(int x, int fa) {
        long p = price[x], maxS1 = p, maxS2 = 0;
        for (var y : g[x])
            if (y != fa) {
                var res = dfs(y, x);
                long s1 = res[0], s2 = res[1];

                ans = Math.max(ans, Math.max(maxS1 + s2, maxS2 + s1));
                maxS1 = Math.max(maxS1, s1 + p);
                maxS2 = Math.max(maxS2, s2 + p);
            }
        return new long[]{maxS1, maxS2};
    }
}

作者:灵茶山艾府
链接:https://leetcode.cn/problems/difference-between-maximum-and-minimum-price-sum/solutions/2062782/by-endlesscheng-5l70/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 复杂度
    • 时间复杂度:O ( n ) O(n)O (n )
    • 空间复杂度:O ( n ) O(n)O (n )

Original: https://blog.csdn.net/Tikitian/article/details/128738191
Author: TIkitianya
Title: 周赛328总结

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/812039/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Linux驱动开发:字符设备驱动开发实战

    Linux驱动开发:字符设备驱动开发实战 一、工程创建 VSCode 创建工程,设置 C/C++ 配置,导入 linux kernel 源码目录,方便 vscode 写代码自动补全…

    Python 2023年11月7日
    034
  • 秒级查询之开源分布式SQL查询引擎Presto实操-上

    @ 概述 定义 概念 架构 优缺点 连接器 部署 集群安装 常用配置说明 资源管理安装模式 安装命令行界面 基于Tableau Web 连接器 调优 数据存储 查询SQL优化 无缝…

    Python 2023年10月13日
    037
  • flutter系列之:flutter中常用的Stack layout详解

    简介 Stack详解 Stack的属性 Stack的使用 总结 简介 对于现代APP的应用来说,为了更加美观,通常会需要用到不同图像的堆叠效果,比如在一个APP用户背景头像上面添加…

    Python 2023年10月21日
    024
  • pytorch数据格式转换

    pytorch数据格式转换 1. numpy转换为tensor torch.tensor([ ], dtype=, device= ) device = ‘cuda:0’ if t…

    Python 2023年8月29日
    057
  • python sys模块作用_python os和sys模块的区别

    Python sys模块 是做什么的 sys模块包括了一组非常实用的服务,内含很多函数方法和变量,用来处理Python运行时配置以及资源,从而可以与前当程序之外的系统环境交互。 s…

    Python 2023年9月25日
    039
  • rh358 007 mariadb ansible mariadb

    博客园 :当前访问的博文已被密码保护 请输入阅读密码: Original: https://www.cnblogs.com/supermao12/p/16671588.htmlAu…

    Python 2023年6月6日
    073
  • 【Python】深究模块导入:from .. import .. import ..

    模块导入:from .. import ..\ import .. * – from .. import .. 用法 – + * 从py模块中导入变量,im…

    Python 2023年8月2日
    072
  • 独立脚本pytest封装

    建议先在普通的.py文件中调用要封装的测试脚本 方法1:捕获异常-抛出异常-处理异常 try: 可能会报错的代码 except Exception as e : print (e)…

    Python 2023年9月12日
    044
  • 阿里云天池打卡笔记兼错题集

    一、python训练营 raise关键字:抛出指定异常 try: raise NameError(‘HiThere’) except NmaeError: print(‘An ex…

    Python 2023年8月17日
    043
  • django导入excel

    web架构:前后端分离,前端使用vue,后端使用django 的rest framework django版本3.2 django-excel 版本0.0.10 djangores…

    Python 2023年8月4日
    046
  • 简析 Linux 的 CPU 时间

    从 CPU 时间说起… 下面这个是 top 命令的界面,相信大家应该都不陌生。 top – 19:01:38 up 91 days, 23:06, 1 user, lo…

    Python 2023年10月19日
    081
  • 存储器详解

    有五种类型的内存,即寄存器、高速缓存、内存、磁盘和磁带。 [En] There are five types of memory, namely, register, cache,…

    Python 2023年5月23日
    046
  • ssti总结

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xhoPMsmE-1663477021410)(images/LjZ9mqCMvT6xyFlqLIky…

    Python 2023年8月15日
    048
  • 如何使用分治算法的思想,分治技巧详解

    分治算法 分治算法的思想 分治算法和递归的区别 使用分治算法需要满足的条件 经典题目 1、二分搜索 2、第一个错误的版本 3、快速排序 4、归并排序 5、数组中的逆序对 6、汉诺塔…

    Python 2023年10月15日
    026
  • 使用Jupyter记事本记录和制作.NET可视化笔记

    前言:对于记录笔记的工具特别多,不过对于程序员来说,记录笔记+程序代码+运行结果演示可以同时存在,无疑会极大增加我们的笔记的可读性和体验感。以前在写python的时候,使用jupy…

    Python 2023年10月15日
    038
  • 「python」如何有效利用Scrapy框架建立网页爬虫看这篇就懂——第三篇

    在「python」实用的Scrapy框架安装指南,开始你的第一个专案-第2篇文章,完成Scrapy框架的安装以及专案的建立后,接下来,就可以在其中开发网页爬虫,而在开发之前,又有哪…

    Python 2023年10月6日
    051
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球