当前位置: 首页 > news >正文

【周赛复盘】力扣第 312 场单周赛

1.按身高排序

1)题目描述

给你一个字符串数组 names ,和一个由 互不相同 的正整数组成的数组 heights 。两个数组的长度均为 n

对于每个下标 inames[i]heights[i] 表示第 i 个人的名字和身高。

请按身高 降序 顺序返回对应的名字数组 names

2)原题链接

LeetCode.6188. 按身高排序

3)思路解析

( 1 ) (1) (1)考虑将名字和身高放一起,进行二维排序,按身高来排。

4)模板代码

public String[] sortPeople(String[] names, int[] heights) {
            int n=names.length;
            Node[] node=new Node[n];
        for (int i = 0; i < n; i++) {
            node[i]=new Node(names[i],heights[i]);
        }
        Arrays.sort(node, Comparator.comparing(a->a.d));
        int pre=n-1;
        for (int i = 0; i <n; i++) {
            names[i]=node[pre--].s;
        }
        return names;
    }
    class Node{
        String s;
        int d;
        public Node(String s, int d) {
            this.s = s;
            this.d = d;
        }
    }

5)算法与时间复杂度

算法:排序
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)

2.按位与最大的最长子数组

1.题目描述

给你一个长度为 n 的整数数组 nums

考虑 nums中进行 **按位与(bitwise AND)**运算得到的值 最大非空 子数组。

  • 换句话说,令 knums 任意 子数组执行按位与运算所能得到的最大值。那么,只需要考虑那些执行一次按位与运算后等于 k 的子数组。
    返回满足要求的 最长 子数组的长度。

数组的按位与就是对数组中的所有数字进行按位与运算。

子数组 是数组中的一个连续元素序列。

2)原题链接

LeetCode.6189. 按位与最大的最长子数组

3)思路解析

( 1 ) (1) (1)首先我们要思考:这个最大值k会是多少呢?
这得从与运算&的性质出发,我们知道:0&0=0,1&0=0,1&1=1。对于某一个二进制位,只有可能从1变为0,不可能从0变为1。这就说明对于一个数 x x x ,如果与上区间 [ 1 , x − 1 ] [1,x-1] [1,x1]的数,它是不可能变大的,只可能变小,当它与上自身时值不变。
( 2 ) (2) (2)根据上述结论,我们可知道k的值就是数组中的最大值,问题则转换为求原数组内最大值max最长连续出现的区间,我们可以使用双指针进行求解。

4)模板代码

class Solution {
 public int longestSubarray(int[] arr) {
        int mx=0;
        for (int i = 0; i < arr.length; i++) {
            mx=Math.max(arr[i],mx);
        }
        int ans=0;
        for (int i = 0; i <arr.length; i++) {
            if (arr[i]==mx){
                int s=1;
                int j;
                for (j = i+1; j <arr.length; j++) {
                    if (arr[j]==mx) s++;
                    else{
                        break;
                    }
                }
                i=j;
                ans=Math.max(s,ans);
            }
        }
        return ans;
    }
}

5)算法与时间复杂度

算法:双指针
时间复杂度: O ( n ) O(n) O(n)

3.找到所有好下标

1.题目描述

给你一个大小为 n 下标从 0 开始的整数数组 nums 和一个正整数 k

对于 k <= i < n - k 之间的一个下标 i ,如果它满足以下条件,我们就称它为一个 下标:

  • 下标 i 之前 的 k 个元素是 非递增的 。
  • 下标 i 之后 的 k 个元素是 非递减的 。
    按 升序 返回所有好下标。

子数组 是数组中的一个连续元素序列。

2)原题链接

LeetCode.6190. 找到所有好下标

3)思路解析

( 1 ) (1) (1)考虑到我们需要判断的区间都是长度为k的,自然我们想到使用滑动窗口,去预处理出所有长度为k,非递增以及非递减的区间,分别使用两个set存下这些区间的起始下标。当我们判断下标 x x x 是否是一个好下标时,则要去判断区间 [ x − k , x − 1 ] [x-k,x-1] [xk,x1]是否非递增,如果存非递增区间的set包含 x − k x-k xk 这点说明符合。同时需要判断区间 [ x + 1 , x + k ] [x+1,x+k] [x+1,x+k]是否是非递减,我们去另外一个set去判断是否存在点 x + 1 x+1 x+1 即可,两者都存在说明 x x x 是一个好下标。

4)模板代码

class Solution {
      public List<Integer> goodIndices(int[] a, int k) {
        Set<Integer> set1 = new HashSet<>();
        Set<Integer> set2 = new HashSet<>();
        int n = a.length;
        int ans = 0;
        for (int i = 0, j = 0; i < n; i++) {
            if (i > 0 && a[i] <= a[i - 1]) ans++;
            if (i - j + 1 > k) {
                if (a[j] >= a[j + 1]) ans--;
                j++;
            }
            if (i - j + 1 == k && ans == k - 1) {
                set1.add(i);
            }
        }
        ans=0;
        for (int i = 0, j = 0; i < n; i++) {
            if (i > 0 && a[i] >= a[i - 1]) ans++;
            if (i - j + 1 > k) {
                if (a[j] <= a[j + 1]) ans--;
                j++;
            }
            if (i - j + 1 == k && ans == k - 1) {
                set2.add(i);
            }
        }
        List<Integer> list=new ArrayList<>();
        for (int i = k; i <=n-k-1; i++) {
            int l=i-1,r=i+k;
            if (set1.contains(l)&&set2.contains(r)) list.add(i);
        }
        return list;
    }
}

5)算法与时间复杂度

算法:滑动窗口 哈希表
时间复杂度: O ( n ) O(n) O(n)

4.好路径的数目

1.题目描述

给你一棵 n 个节点的树(连通无向无环的图),节点编号从 0n - 1 且恰好有 n - 1 条边。

给你一个长度为 n 下标从 0 开始的整数数组vals,分别表示每个节点的值。同时给你一个二维整数数组 edges ,其中 edges[i] = [ai, bi] 表示节点 ai bi 之间有一条 无向 边。

一条 好路径 需要满足以下条件:

  1. 开始节点和结束节点的值 相同 。
  2. 开始节点和结束节点中间的所有节点值都 小于等于 开始节点的值(也就是说开始节点的值应该是路径上所有节点的最大值)。
    请你返回不同好路径的数目。

注意,一条路径和它反向的路径算作 同一 路径。比方说, 0 -> 11 -> 0 视为同一条路径。单个节点也视为一条合法路径。
在这里插入图片描述

2)原题链接

LeetCode.6190. 找到所有好下标

3)解题思路

( 1 ) (1) (1)由于每个相同节点的值相互到达的前提是不能经过大于自己的值的节点,所以我们先假设所有的点都是独立的,从节点值小的开始合并,当两个节点的值在同一个联通块中说明存在一条好路径,因为我们是从小到达合并的,所以一定路线上一定不存在大于当前节点值的节点。我们可以使用并查集完成这个操作。
( 2 ) (2) (2)当一个联通块出现 x x x 个相同值的节点时,可以产生的好路径数目为 x ∗ ( x − 1 ) / 2 x*(x-1)/2 x(x1)/2,我们统计进答案中,最后加上节点个数为最终答案。

4)模板代码

struct UF {
    std::vector<int> f, siz;
    UF(int n) : f(n), siz(n, 1) { std::iota(f.begin(), f.end(), 0); }
    int find(int x) {
        while (x != f[x]) x = f[x] = f[f[x]];
        return x;
    }
    bool same(int x, int y) { return find(x) == find(y); }
    bool merge(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) return false;
        siz[x] += siz[y];
        f[y] = x;
        return true;
    }
    int size(int x) { return siz[find(x)]; }
};
class Solution {
public:
    int numberOfGoodPaths(vector<int>& vals, vector<vector<int>>& edges) {
        int n = vals.size();
        vector<vector<int>> g(n);
        UF uf(n);
        map<int, vector<int>> mp;
        for (int i = 0; i < n; i++) {
            mp[vals[i]].push_back(i);
        }
        for (auto &v : edges) {
            g[v[0]].push_back(v[1]);
            g[v[1]].push_back(v[0]);
        }
        int res = 0;
        //v是集合
        for (auto [k, v] : mp) {
            //所有的x的节点值是相同的
            for (auto x : v) {
                for (auto y : g[x]) {
                    if (vals[y] <= vals[x]) {
                        uf.merge(x, y);
                    }
                }
            }
            map<int, int> count;
            for(auto x:v){
                count[uf.find(x)]++;
            }
            for(auto [kk,vv]:count){
                res+=vv*(vv-1)/2;
            }
        }
        return res+n;
    }
};

5)算法与时间复杂度

算法:并查集
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)

相关文章:

  • QT通过QSS文件样式表设置改变窗体与按钮背景外观
  • kotlin基础知识
  • Keras学习记录之模型
  • LeetCode 0329. 矩阵中的最长递增路径
  • JavaEE:线程安全问题的原因和解决方案
  • Linux/CentOS 安装 flutter 与 jenkins 构建 (踩坑)
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • 随想录一期 day4 [24. 两两交换链表中的节点|19. 删除链表的倒数第 N 个结点|面试题 02.07. 链表相交|142. 环形链表 II]
  • iOS动画相关
  • LeetCode往完全二叉树添加节点
  • Linux、docker、kubernetes、MySql、Shell运维快餐
  • 基数(桶)排序算法详解之C语言版
  • 生成模型的中Attention Mask说明
  • java毕业设计企业固定资产管理系统源码+lw文档+mybatis+系统+mysql数据库+调试
  • Java---Java Web---JSP
  • 自己简单写的 事件订阅机制
  • Elasticsearch 参考指南(升级前重新索引)
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • JavaScript学习总结——原型
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • Python学习之路13-记分
  • SpiderData 2019年2月16日 DApp数据排行榜
  • Terraform入门 - 1. 安装Terraform
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • 好的网址,关于.net 4.0 ,vs 2010
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 深度学习在携程攻略社区的应用
  • 算法-插入排序
  • 线上 python http server profile 实践
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • (3)llvm ir转换过程
  • (附源码)计算机毕业设计高校学生选课系统
  • (算法)Travel Information Center
  • (小白学Java)Java简介和基本配置
  • (学习日记)2024.01.19
  • (一)认识微服务
  • (转)关于pipe()的详细解析
  • .NET Core 通过 Ef Core 操作 Mysql
  • .NET 表达式计算:Expression Evaluator
  • .net 重复调用webservice_Java RMI 远程调用详解,优劣势说明
  • .net项目IIS、VS 附加进程调试
  • /proc/stat文件详解(翻译)
  • [ C++ ] template 模板进阶 (特化,分离编译)
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(白虎组)
  • [ 转载 ] SharePoint 资料
  • [30期] 我的学习方法
  • [BJDCTF2020]The mystery of ip
  • [bzoj1006]: [HNOI2008]神奇的国度(最大势算法)
  • [C# WPF] DataGrid选中行或选中单元格的背景和字体颜色修改
  • [Fri 26 Jun 2015 ~ Thu 2 Jul 2015] Deep Learning in arxiv