周赛328总结

news/2023/6/7 22:58:33

周赛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(nlogU)O(nlogU)O(nlogU),U=max(nums)U=max(nums)U=max(nums)
      • 空间复杂度: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 <= row2icol1i <= y <= col2imat[x][y]1

返回执行完所有操作后得到的矩阵 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(n2∗q)O(n^2*q)O(n2q)qqqqueriesqueriesqueries的长度
    • 空间复杂度:O(1)O(1)O(1)

二维差分

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

  • 思路:使用二维差分数组记录每个区域的变化量,然后通过二维前缀和数组求得每个位置的值

  • 实现

    • 二维差分数组div中的每一个格子记录的是「以当前位置为区域的左上角(区域右下角恒定为原数组的右下角)的值的变化量」【应该不固定 可以倒转】

    • 二维差分数组的二维前缀和数组sum,即差分数组以当前位置为右下角,原数组的左上角为左上角的区域和

    • 因此,如果要求 (x1,y1)(x1, y1)(x1,y1) 作为左上角,(x2,y2)(x2, y2)(x2,y2) 作为右下角的区域值增加xxx的时候,可以利用二维差分数组快速求解,此时相当于二维差分矩阵上对(x1,y1)(x1,y1)(x1,y1)增加xxx,对(x2+1,y1)(x2+1,y1)(x2+1,y1)(x1,y2+1)(x1,y2+1)(x1,y2+1)减小xxx,再对重复区域(x2+1,y2+1)(x2+1,y2+1)(x2+1,y2+1)增加xxx

    • 要求得二维数组每个位置(x1,y1)(x1,y1)(x1,y1)的变化量,即求二维差分数组的二维前缀和数组sum,即差分数组以当前位置为右下角,原数组的左上角为左上角的区域和
      sum[i,j]=sum[i−1][j]+sum[i][j−1]−sum[i−1][j−1]+dev[i][j]sum[i,j] = sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+dev[i][j] sum[i,j]=sum[i1][j]+sum[i][j1]sum[i1][j1]+dev[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(n2+q)O(n^2+q)O(n2+q)qqqqueriesqueriesqueries的长度
          • 空间复杂度:O(1)O(1)O(1)
      • div数组边界可以+2,方便处理0

        div[1:n][1:n]div[1:n][1:n]div[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+1l+1l+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);        // 如果子数组对数大于k,那么右移左边界至最大可以去到的值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); // 这里加上 p 是因为 x 必然不是叶子}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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.exyb.cn/news/show-4566600.html

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

前端js实现文件多次添加累加上传和选择删除(django+js)- 添加累加文件上传 (一)

前言 原本的多文件上传功能在选择文件时&#xff0c;只能通过同一范围的鼠标框选或者ctrl/shift多选取选择文件&#xff0c;这样选择文件很不灵活&#xff0c;而且在确定之后如果漏选了文件&#xff0c;再次点击上传按钮时会清空表单里的文件信息&#xff0c;只能重复之前的操…

国内目前最强的电视盒子,当贝B3 Pro用配置和体验秒杀同行

国内目前最强的电视盒子是哪一款呢&#xff1f;随着科技的发展&#xff0c;电视盒子的种类也层出不穷&#xff0c;但真正杀出重围的没几款&#xff0c;现在主流盒子中当属当贝盒子和小米盒子比较出名&#xff0c;国内目前最强的电视盒子是当贝B3 Pro&#xff0c;因为小米盒子普…

腾讯云公布大数据平台最新数据,日实时计算量超40万亿

9月11日&#xff0c;在2020腾讯全球数字生态大会上&#xff0c;腾讯云副总裁刘煜宏透露&#xff0c;腾讯云大数据平台的算力弹性资源池达500万核&#xff0c;每日分析任务数达1500万&#xff0c;每日实时计算次数超过40万亿&#xff0c;能支持超过一万亿维度的数据训练。腾讯云…

黄仁勋:GPU,打折!

点击下方卡片&#xff0c;关注“自动驾驶之心”公众号ADAS巨卷干货&#xff0c;即可获取点击进入→自动驾驶之心技术交流群后台回复【领域综述】获取自动驾驶全栈近80篇综述论文&#xff01;新的GPU系列上市在即&#xff0c;英伟达“忍痛”宣布&#xff1a;打折&#xff01;打折…

NVIDIA AGX XAVIER(3分钟攻破英伟达盒子联网与VSCode安装)

一、英伟达盒子联网 1、笔记本连接上无线网 2、按“WinR”&#xff0c;打开【运行】 3、输入“ncpa.cpl”,回车&#xff0c;将进入“网络连接” 3、找到笔记本连接的无线网&#xff0c;右击&#xff0c;选择“属性”4、进入“WLAN属性”窗口&#xff0c;选择“共享”&…

android7.0新特性 tv,英伟达为SHIELD TV升级安卓7.0 旧款用户可以升级

【TechWeb报道】黄仁勋在今年的CES 2017展会上发布了第二代神盾机顶盒&#xff0c;支持4K超清分辨率&#xff0c;全新设计的手柄&#xff0c;更完善的云串流功能以及搭载自主研发的芯片&#xff0c;让第二代神盾机顶盒成为了目前性能最强的安卓机顶盒&#xff0c;而现在英伟达对…

day18|235. 二叉搜索树的最近公共祖先、701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点

235. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最近公共祖先表示为一个结点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08…

HDU 6083 度度熊的午饭时光(01背包+记录路径)

http://acm.hdu.edu.cn/showproblem.php?pid6083 题意&#xff1a; 思路&#xff1a; 01背包路径记录。 题目有点坑&#xff0c;我一开始逆序枚举菜品&#xff0c;然后一直WA&#xff0c;可能这样的话路径记录会有点问题。 1 #include<iostream>2 #include<algorithm…