LeetCode刷题【树状数组、并查集】

目录

  • 树状数组
    • 307. 区域和检索 - 数组可修改
      • 406. 根据身高重建队列
      • 673. 最长递增子序列的个数
      • 1409. 查询带键的排列
  • 并查集
      • 128. 最长连续序列
      • 130. 被围绕的区域

树状数组

307. 区域和检索 - 数组可修改

给你一个数组 nums ,请你完成两类查询。

其中一类查询要求 更新 数组 nums 下标对应的值
另一类查询要求返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 和 ,其中 left <= right

实现 NumArray 类:

NumArray(int[] nums) 用整数数组 nums 初始化对象
void update(int index, int val) 将 nums[index] 的值 更新 为 val
int sumRange(int left, int right) 返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 和 (即,nums[left] + nums[left + 1], ..., nums[right])
class NumArray {
private:
    vector<int> tree;
    vector<int> &nums;
    int lowBit(int x){
        return x & -x;
    }
    void add(int index, int val){
        while(index < tree.size()){
            tree[index] += val;
            index += lowBit(index);
        }
    }
    int prefixSum(int index){
        int sum = 0;
        while(index > 0){
            sum += tree[index];
            index -= lowBit(index);
        }
        return sum;
    }

public:
    NumArray(vector<int>& nums) : tree(nums.size() + 1), nums(nums) {
        for(int i = 0; i < nums.size(); i++){
            add(i + 1, nums[i]);
        }
    }
    
    void update(int index, int val) {
        add(index + 1, val - nums[index]);
        nums[index] = val;
    }
    
    int sumRange(int left, int right) {
        return prefixSum(right + 1) - prefixSum(left);
    }
};

406. 根据身高重建队列

假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。

请你重新构造并返回输入数组 people 所表示的队列。返回的队列应该格式化为数组 queue ,其中 queue[j] = [hj, kj] 是队列中第 j 个人的属性(queue[0] 是排在队列前面的人)。

示例 1:
输入:people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
输出:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
解释:
编号为 0 的人身高为 5 ,没有身高更高或者相同的人排在他前面。
编号为 1 的人身高为 7 ,没有身高更高或者相同的人排在他前面。
编号为 2 的人身高为 5 ,有 2 个身高更高或者相同的人排在他前面,即编号为 0 和 1 的人。
编号为 3 的人身高为 6 ,有 1 个身高更高或者相同的人排在他前面,即编号为 1 的人。
编号为 4 的人身高为 4 ,有 4 个身高更高或者相同的人排在他前面,即编号为 0、1、2、3 的人。
编号为 5 的人身高为 7 ,有 1 个身高更高或者相同的人排在他前面,即编号为 1 的人。
因此 [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] 是重新构造后的队列。
class Solution {
public:
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        sort(people.begin(), people.end(), [](const vector<int>& u, const vector<int>& v){
            return u[0] < v[0] || (u[0] == v[0] && u[1] > v[1]);
        });
        int n = people.size();
        vector<vector<int>> ans(n);
        for(vector<int>& person : people){
            int spaces = person[1] + 1;
            for(int i = 0; i < n; i++){
                if(ans[i].empty()){
                    spaces--;
                    if(!spaces){
                        ans[i] = person;
                        break;
                    }
                }
            }
        }
        return ans;
    }
};

673. 最长递增子序列的个数

给定一个未排序的整数数组 nums , 返回最长递增子序列的个数 。

注意 这个数列必须是 严格 递增的。

示例 1:
输入: [1,3,5,4,7]
输出: 2
解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[1, 3, 5, 7]。
class Solution {
public:
    int findNumberOfLIS(vector<int>& nums) {
        int n = nums.size();
        vector<int> dp(n, 1), cnt(n, 1);
        int maxs = 1;
        int count = 0;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < i; j++){
                if(nums[j] < nums[i]){
                    if(dp[i] < dp[j] + 1){
                        dp[i] = dp[j] + 1;
                        cnt[i] = cnt[j];
                    }
                    else if(dp[i] == dp[j] + 1){
                        cnt[i] += cnt[j];
                    }
                }
            }
            if(dp[i] > maxs){
                maxs = dp[i];
                count = cnt[i];
            }
            else if(dp[i] == maxs){
                count += cnt[i];
            }
        }
        return count;
    }
};

1409. 查询带键的排列

给定一个正整数数组 queries ,其取值范围在 1 到 m 之间。 请你根据以下规则按顺序处理所有 queries[i](从 i=0 到 i=queries.length-1):

首先,你有一个排列 P=[1,2,3,...,m]。
对于当前的 i ,找到 queries[i] 在排列 P 中的位置(从 0 开始索引),然后将它移到排列 P 的开头(即下标为 0 处)。注意, queries[i] 的查询结果是 queries[i] 在 P 中移动前的位置。

返回一个数组,包含从给定 queries 中查询到的结果。

示例 1:
输入:queries = [3,1,2,1], m = 5
输出:[2,1,2,1] 
解释:处理 queries 的过程如下:
对于 i=0: queries[i]=3, P=[1,2,3,4,5], 3 在 P 中的位置是 2,然后我们把 3 移动到 P 的开头,得到 P=[3,1,2,4,5] 。
对于 i=1: queries[i]=1, P=[3,1,2,4,5], 1 在 P 中的位置是 1,然后我们把 1 移动到 P 的开头,得到 P=[1,3,2,4,5] 。 
对于 i=2: queries[i]=2, P=[1,3,2,4,5], 2 在 P 中的位置是 2,然后我们把 2 移动到 P 的开头,得到 P=[2,1,3,4,5] 。
对于 i=3: queries[i]=1, P=[2,1,3,4,5], 1 在 P 中的位置是 1,然后我们把 1 移动到 P 的开头,得到 P=[1,2,3,4,5] 。 
因此,包含结果的数组为 [2,1,2,1] 。  
struct BIT{
    vector<int> a;
    int n;
    BIT(int _n): n(_n), a(_n + 1){}
    static int lowbit(int x){
        return x & (-x);
    }
    int query(int x){
        int ret = 0;
        while(x){
            ret += a[x];
            x -= lowbit(x);
        }
        return ret;
    }
    void update(int x, int dt){
        while(x <= n){
            a[x] += dt;
            x += lowbit(x);
        }
    }
};

class Solution {
public:
    vector<int> processQueries(vector<int>& queries, int m) {
        int n = queries.size();
        BIT bit(m + n);
        
        vector<int> pos(m + 1);
        for (int i = 1; i <= m; ++i) {
            pos[i] = n + i;
            bit.update(n + i, 1);
        }
        
        vector<int> ans;
        for (int i = 0; i < n; ++i) {
            int& cur = pos[queries[i]];
            bit.update(cur, -1);
            ans.push_back(bit.query(cur));
            cur = n - i;
            bit.update(cur, 1);
        }
        return ans;
    }
};

并查集

128. 最长连续序列

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例 1:
输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。

使用哈希表,先找到最小的元素,再遍历,我之前的方法是直接使用sort(nums.begin(), nums.end());

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_set<int> num_set;
        for(int num : nums){
            num_set.insert(num);
        }
        int longstStreak = 0;
        for(int num : num_set){
            if(!num_set.count(num - 1)){
                int currentNum = num;
                int currentStreak = 1;
                while(num_set.count(currentNum + 1)){
                    currentNum += 1;
                    currentStreak += 1;
                }
                longstStreak = max(longstStreak, currentStreak);
            }
        }
        return longstStreak;
    }
};

130. 被围绕的区域

给你一个 m x n 的矩阵 board ,由若干字符 ‘X’ 和 ‘O’ ,找到所有被 ‘X’ 围绕的区域,并将这些区域里所有的 ‘O’ 用 ‘X’ 填充。
在这里插入图片描述

考虑边界上的‘O’,将其置为‘A’,之后再对矩阵中剩下的‘O’进行操作。

class Solution {
public:
    int n, m;
    void dfs(vector<vector<char>>& board, int x, int y){
        if(x < 0 || x >= n || y < 0 || y>= m || board[x][y] != 'O'){
            return;
        }
        board[x][y] = 'A';
        dfs(board, x + 1, y);
        dfs(board, x - 1, y);
        dfs(board, x, y + 1);
        dfs(board, x, y - 1);
    }
    void solve(vector<vector<char>>& board) {
        n = board.size();
        if(n == 0){
            return;
        }
        m = board[0].size();
        for(int i = 0; i < n; i++){
            dfs(board, i, 0);
            dfs(board, i, m - 1);
        } 
        for(int i = 1; i < m - 1; i++){
            dfs(board, 0, i);
            dfs(board, n - 1, i);
        }
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                if(board[i][j] == 'A'){
                    board[i][j] = 'O';
                }
                else if(board[i][j] == 'O'){
                    board[i][j] = 'X';
                }
            }
        }         
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTML案例-1.标签练习

效果 源码 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head&g…

基于HSV色度空间的图像深度信息提取算法FPGA实现,包含testbench和MATLAB辅助验证程序

目录 1.算法运行效果图预览 ​编辑2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 将FPGA结果导入到matlab显示结果如下&#xff1a; matlab的对比测试结果如下&#xff1a; 2.算法运行软件版本 vivado2019.2 matlab2022a…

(css)vue 自定义背景 can‘t resolve

(css)vue 自定义背景 can’t resolve 旧写法&#xff1a; background-image: url(/assets/images/step-bg.jpg);background-size: 100% 100%; 新写法&#xff1a; background-image: url(~/assets/images/step-bg.jpg);background-size: 100% 100%; 解决参考&#xff1a;https…

Unity在UGUI上通过绘制网格顶点自由画线

该插件的实现是使用UI组件的绘图API来动态生成和修改几何形状&#xff0c;可自由动态更改画线的粗细、拐角圆滑度、颜色&#xff0c;自由增减节点&#xff0c;不额外增加gameobject&#xff0c;并且在原生的UGUI上以ScreenSpace-Overlay的状态下&#xff0c;显示效果如下所示 …

Spring Boot+Vue前后端分离项目如何部署到服务器

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

k8s集群部署elk

一、前言 本次部署elk所有的服务都部署在k8s集群中&#xff0c;服务包含filebeat、logstash、elasticsearch、kibana&#xff0c;其中elasticsearch使用集群的方式部署&#xff0c;所有服务都是用7.17.10版本 二、部署 部署elasticsearch集群 部署elasticsearch集群需要先优化…

CMU module design

CMU 1.概要&#xff1a; 时钟单元可以产生主频时钟信号&#xff0c;作为整个单片机系统的时钟源。且对各个外设提供时钟。 2.验证参数 参数编号参数名称可选项备注1测试模块CMU用于标识被测试的模块2模块功能模块功能描述被测试模块的功能3测试项测试项具体的测试项目4测试子…

Java使用Selenium实现自动化测试以及全功能爬虫

前言 工作中需要抓取一下某音频网站的音频&#xff0c;我就用了两个小时学习弄了一下&#xff0c;竟然弄出来&#xff0c;这里分享记录一下。 springboot项目 Selenium Java使用Selenium实现自动化测试以及全功能爬虫 前言1 自动化测试2 java中集成Selenium3 添加浏览器驱动4…

构建部署_Docker常用命令

构建部署_Docker常见命令 启动命令镜像命令容器命令 启动命令 启动docker&#xff1a;systemctl start docker 停止docker&#xff1a;systemctl stop docker 重启docker&#xff1a;systemctl restart docker 查看docker状态&#xff1a;systemctl status docker 开机启动&…

【力扣白嫖日记】601.体育馆的人流量

前言 练习sql语句&#xff0c;所有题目来自于力扣&#xff08;https://leetcode.cn/problemset/database/&#xff09;的免费数据库练习题。 今日题目&#xff1a; 601.体育馆的人流量 表&#xff1a;Stadium 列名类型idintvisit_datedatepeopleint 编写解决方案找出每行的…

Transformer的前世今生 day01(预训练、统计语言模型)

预训练 在相似任务中&#xff0c;由于神经网络模型的浅层是通用的&#xff0c;如下图&#xff1a; 所以当我们的数据集不够大&#xff0c;不能产生性能良好的模型时&#xff0c;可以尝试让模型B在用模型A的浅层基础上&#xff0c;深层的部分自己生成参数&#xff0c;减小数据集…

H266开源视频编码器VVENC现状

VVenC 是由 Fraunhofer HHI 研究团队开发的&#xff0c;主要是视频编码系统组。HHI 是欧洲最大的研究组织 Fraunhofer 协会的成员&#xff0c;该协会是德国的一个大型非营利性组织。源代码在&#xff1a; https://github.com/fraunhoferhhi/vvenc VVenC几乎与H.266视频标准同时…

【01】htmlcssgit网络基础知识

一、html&css 防脱发神器 一图胜千言 使用border-box控制尺寸更加直观,因此,很多网站都会加入下面的代码 * {margin: 0;padding: 0;box-sizing: border-box; }颜色的 alpha 通道 颜色的 alpha 通道标识了色彩的透明度,它是一个 0~1 之间的取值,0 标识完全透明,1…

常用大数据组件的Web端口号总结

常用大数据组件的Web端口号总结 网站访问方式 在地址栏中输入虚拟机名称对应组建的Web端口号&#xff0c;回车访问。 常用大数据组建的Web端口号 Hadoop HDFS&#xff1a;9870Hadoop YARN ResourceManager&#xff1a;8088JobHistoryServer&#xff1a;19888 Zeppelin&…

因聚而生 数智有为丨软通动力携子公司鸿湖万联亮相华为中国合作伙伴大会2024

3月14日&#xff0c;以“因聚而生 数智有为”为主题的“华为中国合作伙伴大会2024”在深圳隆重开幕。作为华为的重要合作伙伴和本次大会钻石级&#xff08;最高级&#xff09;合作伙伴&#xff0c;软通动力深度参与本次盛会&#xff0c;携前沿数智化技术成果和与华为的联合解决…

使用ChatGPT高效完成简历制作[中篇3]-有爱AI实战教程(十)

演示站点&#xff1a; https://ai.uaai.cn 对话模块 官方论坛&#xff1a; www.jingyuai.com 京娱AI 一、导读&#xff1a; 在使用 ChatGPT 时&#xff0c;当你给的指令越精确&#xff0c;它的回答会越到位&#xff0c;举例来说&#xff0c;假如你要请它帮忙写文案&#xff0c;…

pdf文件属性的删除

pdf文件属性的删除 投标过程中需要处理文件属性&#xff0c;特别是word文件属性以及pdf文件的处理 这里讲解pdf文件属性的处理 word处理在我的另外一个博客中&#xff0c;word文件属性的处理 https://ht666666.blog.csdn.net/article/details/134102504 一般用 adobe acroba…

【每日力扣】 修剪二叉搜索树与复原 IP 地址

&#x1f525; 个人主页: 黑洞晓威 &#x1f600;你不必等到非常厉害&#xff0c;才敢开始&#xff0c;你需要开始&#xff0c;才会变的非常厉害。 669. 修剪二叉搜索树 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&am…

linux用git拉取我云端以及git处理冲突

拉取后切换一个跟云端分支(dev)一样的 git branch --set-upstream-toorigin/dev dev 之后就同步了 A在dev分支写了iii,提交 B在dev分支写了hhh,提交,冲突 怎么修改,B把云端的拉下来,随便改改就行

【Redis】基于Redis实现查询缓存

1.缓存更新策略 主动更新用的最多。  主动更新一般是由缓存的调用者&#xff0c;在更新数据库的同时&#xff0c;更新缓存。 操作缓存和数据库时有三个问题需要考虑&#xff1a; 删除缓存还是更新缓存&#xff1f; 更新缓存&#xff1a;每次更新数据库都更新缓存&#xff0…
最新文章