Leetcode | 1534 统计好三元组

news2024/12/23 13:53:55

1534 统计好三元组

文章目录

  • [1534 统计好三元组](https://leetcode.cn/problems/count-good-triplets/description/)
    • 题目
      • 解法1 暴力穷举
      • 解法2 枚举优化

题目

给你一个整数数组 arr ,以及 abc 三个整数。请你统计其中好三元组的数量。

如果三元组 (arr[i], arr[j], arr[k]) 满足下列全部条件,则认为它是一个 好三元组

  • 0 <= i < j < k < arr.length
  • |arr[i] - arr[j]| <= a
  • |arr[j] - arr[k]| <= b
  • |arr[i] - arr[k]| <= c

其中 |x| 表示 x 的绝对值。

返回 好三元组的数量

示例 1:

输入:arr = [3,0,1,1,9,7], a = 7, b = 2, c = 3
输出:4
解释:一共有 4 个好三元组:[(3,0,1), (3,0,1), (3,1,1), (0,1,1)] 。
示例 2:

输入:arr = [1,1,2,2,3], a = 0, b = 0, c = 1
输出:0
解释:不存在满足所有条件的三元组。

提示:

3 <= arr.length <= 100
0 <= arr[i] <= 1000
0 <= a, b, c <= 1000


解法1 暴力穷举

最简单的方法就是暴力穷举,按照题目要求判断即可。

class Solution {
public:
    int countGoodTriplets(vector<int>& arr, int a, int b, int c) {
        int count  =  arr.size();
        int match = 0;
        for (int i =0; i < count - 2; ++i) {
            auto& val_i = arr[i];
            for (int j = i + 1; j < count - 1; ++j) {
                auto& val_j = arr[j];
                if(abs(val_i - val_j) <= a) {
                    for (int k = j + 1; k < count; ++k) {
                        auto& val_k = arr[k];
                        if(abs(val_j - val_k) <= b && abs(val_i - val_k) <= c) {
                            ++match;
                        }
                    }
                }
            }
        }
        return match;
    }
};

解法2 枚举优化

思路与算法

先看题解:

class Solution {
public:
    int countGoodTriplets(vector<int>& arr, int a, int b, int c) {
        int ans = 0, n = arr.size();
        vector<int> sum(1001, 0);
        for (int j = 0; j < n; ++j) {
            for (int k = j + 1; k < n; ++k) {
                if (abs(arr[j] - arr[k]) <= b) {
                    int lj = arr[j] - a, rj = arr[j] + a;
                    int lk = arr[k] - c, rk = arr[k] + c;
                    int l = max(0, max(lj, lk)), r = min(1000, min(rj, rk));
                    if (l <= r) {
                        if (l == 0) {
                            ans += sum[r];
                        }
                        else {
                            ans += sum[r] - sum[l - 1];
                        }
                    }
                }
            }
            for (int k = arr[j]; k <= 1000; ++k) {
                ++sum[k];
            }
        }
        return ans;
    }
};

作者:力扣官方题解
链接:https://leetcode.cn/problems/count-good-triplets/solutions/371340/tong-ji-hao-san-yuan-zu-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

首先,可以根据 ∣ a r r [ j ] − a r r [ k ] ∣ < = b |arr[j] - arr[k]| <= b arr[j]arr[k]<=b的限制条件,找到符合条件的(j,k)二元组

然后根据arr[i] 与 arr[j]、arr[k]的大小关系进行不等式变换
∣ a r r [ i ] − a r r [ j ] ∣ < = a |arr[i] - arr[j]| <= a arr[i]arr[j]<=a

∣ a r r [ i ] − a r r [ k ] ∣ < = c |arr[i] - arr[k]| <= c arr[i]arr[k]<=c

推导出:
a r r [ j ] − a < = a r r [ i ] < = a r r [ j ] + a arr[j] - a <= arr[i] <= arr[j] + a arr[j]a<=arr[i]<=arr[j]+a

a r r [ k ] − c < = a r r [ i ] < = a r r [ k ] + c arr[k] - c <= arr[i] <= arr[k] + c arr[k]c<=arr[i]<=arr[k]+c
因此可以看出 arr[i]同时满足2个区间要求,因此肯定满足2区间的交集,根据左右区间的大小关系,可以得出相交区间为[l, r]

注意,这里 l 和 r 是 arr[i] 的值域范围。

因此,只要知道当$ arr[i]\in[l, r]$时,i 的个数即可。

这就是题解引入了 频次数组的前缀和 sum

看下sum的赋值

vector<int> sum(1001, 0);
for (int j = 0; j < n; ++j) {
        ......
      for (int k = arr[j]; k <= 1000; ++k) {
          ++sum[k];
      }
  }
}

每次遍历 j 的时候,可以获取到 arr[j] 的值,根据arr[j] 的值更新 sum 数组

更新思维:sum 是 std::vector<int>(1001, 0),即 1001个值为0的数组,每当读入1个 arr[j],表示从下标 k = arr[j] 开始,sum 中的值均要+1,也就是在sum中,下标0~(k-1)对应的值没有增加,因为当前 arr[j] 并不小于 0~k-1,而当 下标 >= k(arr[j])时,arr[0]~arr[j] 中数值<=下标的个数才会增加

也就是对于数组来说,每次j 向前1步,通过读取sum[t],就能知道 arr[i] <= t的个数有多少 , sum[t]表示当前数组中,arr[i] <= t 的个数有 sum[t]个

解题思路确实别具一格,减少了1次内嵌for循环,通过遍历 j 的时候,不断更新数组中 小于等于 arr[j] 的个数,更新到 sum 数组中,从而每次根据计算出来的 [l, r],直接从数组中读取 arr[i]的个数,节约了时间。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

怎么把录音转文字?推荐你这三款工具

随着科技不断发展&#xff0c;录音转文字的技术也逐渐被广泛应用于各种场景中。其中最常见的一种就是会议记录。在日常工作中&#xff0c;会议是企业和组织中必不可少的一个环节&#xff0c;但在会议过程中的录音和记录往往需要花费大量的时间和精力。这个时候&#xff0c;我们…

【AI聊天丨 ChatGPT应用案例一】— 仅用30分钟,ChatGPT帮你完成专利交底书!

Hi&#xff0c;大家好&#xff0c;我是零点壹客&#xff0c;今天主要也是想和大家一起唠唠ChatGPT&#xff0c; 尤其这两个月&#xff0c;ChatGPT出奇的火&#xff0c;想必各位圈友们或多或少的都已经有些了解。 ChatGPT的出现很大程度上已经改变了我们的工作方式&#xff0c;尤…

GPT4限制被破解!ChatGPT实现超长文本处理的新方法

目录 前言 使用chat-gpt过程中有哪些痛点 1.无法理解人类情感和主观性 2.上下文丢失 3.约定被打断 那如何去解决这个痛点 Transformer&#xff08;RMT&#xff09;怎么去实现的 1.Transformer 模型 2.RMT模型 3.计算推理速率 4.渐进学习能力 总结 写到最后 大家好…

DeepPyramid:在白内障手术视频中实现金字塔视图和可变形金字塔接收的语义分割

文章目录 DeepPyramid: Enabling Pyramid View and Deformable Pyramid Reception for Semantic Segmentation in Cataract Surgery Videos摘要本文方法模块细节 实验结果 DeepPyramid: Enabling Pyramid View and Deformable Pyramid Reception for Semantic Segmentation in …

探秘 | 简说IP地址以及路由器的功能究竟是什么?

我们都知道我们在上网的时候都有一个IP地址&#xff0c;用来和其他人进行通信和数据交换。 其中IP地址又分为内网地址和外网地址&#xff0c;也叫作私有地址和公有地址。 为什么要区分私有地址和公有地址呢&#xff1f;原因很简单&#xff0c;因为公有的IP地址不够使用了&…

UnityVR--组件4--Ray/Raycast/Linecast/OverlapSphere

目录 Ray/Raycast/Linecast//OverlapSphere简介 Ray类 Physics.Raycast方法 应用1&#xff1a;实现鼠标点击出射线并检测物体 应用2&#xff1a;实现鼠标点击拖拽物体 Physics.Linecast和Physics.OverlapSphere 应用3&#xff1a;进入范围时触发攻击 Ray/Raycast/Lineca…

day13 网络编程Tomcat服务器

c/s架构和b/s架构的区别 c/s架构:客户端软件,直观,体验好,界面美观,安全性高 b/s架构:浏览器–>服务器,可移植性好,开发和维护性好 网络访问的三要素:ip,端口,协议 udp协议和tcp协议的区别 udp协议:只管发送,不管发送到哪里,是否能不能接收,一对多,无连接通信协议 ​ …

蓝桥:前端开发笔面必刷题——Day3 数组(三)

文章目录 &#x1f4cb;前言&#x1f3af;两数之和 II&#x1f4da;题目内容✅解答 &#x1f3af;移除元素&#x1f4da;题目内容✅解答 &#x1f3af;有序数组的平方&#x1f4da;题目内容✅解答 &#x1f3af;三数之和&#x1f4da;题目内容✅解答 &#x1f4dd;最后 &#x…

混沌演练实践(二)-支付加挂链路演练 | 京东云技术团队

1. 背景 当前微服务架构下&#xff0c;各个服务间依赖高&#xff0c;调用关系复杂&#xff0c;业务场景很少可以通过一个系统来实现&#xff0c;常见的业务场景实现基本涉及多个上下游系统&#xff0c;要保证整体链路的稳定性&#xff0c;需要尽量减少系统之间的耦合性&#x…

Elasticsearch与Clickhouse数据存储对比 | 京东云技术团队

1 背景 京喜达技术部在社区团购场景下采用JDQFlinkElasticsearch架构来打造实时数据报表。随着业务的发展Elasticsearch开始暴露出一些弊端&#xff0c;不适合大批量的数据查询&#xff0c;高频次分页导出导致宕机、存储成本较高。 Elasticsearch的查询语句维护成本较高、在聚…

CloudBase CMS的开发注意事项

引言 在进行基于云开发的微信小程序开发时为了减轻工作量打算用CloudBase CMS来减轻工作量&#xff0c;随后去了解并体验了CloudBase CMS的使用&#xff0c;总体来说还有些许问题没有解决&#xff0c;对减轻后台管理工作并没有起到很大的作用。 项目情景 使用CloudBase CMS来管…

Flutter 笔记 | Flutter 基础组件

Text Text 用于显示简单样式文本&#xff0c;它包含一些控制文本显示样式的一些属性&#xff0c;一个简单的例子如下&#xff1a; Text("Hello world",textAlign: TextAlign.left, );Text("Hello world! Im Jack. "*4,maxLines: 1,overflow: TextOverflo…

HACKABLE: III

文章目录 HACKABLE: III实战演练一、前期准备1、相关信息 二、信息收集1、端口扫描2、访问网站3、查看网站源码4、扫描目录5、访问网址6、查看并下载7、访问网站8、查看文件9、解密10、访问网站11、访问网站12、查看文件13、解密14、访问网站15、访问网站16、下载图片17、隐写1…

tcp连接阿里云linux服务器失败

原因&#xff1a; 自己程序bind的是127.0.0.1 应该改成 bind 阿里云的私网地址 client连接的是阿里云公网地址 参考&#xff1a; 阿里云服务器&#xff0c;客户端socket无法连接的问题 - 爱码网 排查过程记录&#xff1a; 1&#xff0c;安全组设置&#xff1a;有正常设置…

【C++】 模板(泛型编程、函数模板、类模板)

文章目录 模板泛型编程概念 函数模板常规使用显式指定及默认值多模板参数模板函数的声明和定义用函数模板优化冒泡排序 类模板常规使用显式指定及默认值多模板参数类中成员函数的定义和声明嵌套的类模板1.类和类型都能确定2.类和类型都不能确定3.类能确定&#xff0c;类型不确定…

Unity3D下如何实现跨平台低延迟的RTMP、RTSP播放

技术背景 好多开发者&#xff0c;希望我们能探讨下Unity平台RTMP或RTSP直播流数据播放和录制相关的模块&#xff0c;实际上&#xff0c;这块流程我们已经聊过多次&#xff0c;无非就是通过原生的RTMP或者RTSP模块&#xff0c;先从协议层拉取到数据&#xff0c;并解包解码&…

常用的表格检测识别方法——表格结构识别方法(上)

第三章 常用的表格检测识别方法 3.2表格结构识别方法 表格结构识别是表格区域检测之后的任务&#xff0c;其目标是识别出表格的布局结构、层次结构等&#xff0c;将表格视觉信息转换成可重建表格的结构描述信息。这些表格结构描述信息包括&#xff1a;单元格的具体位置、单元格…

子网掩码计算方法

子网掩码是用来划分网络的一种方式&#xff0c;它是一个32位的二进制数&#xff0c;用于将IP地址分成网络地址和主机地址两部分。子网掩码中的1表示网络地址&#xff0c;0表示主机地址。计算子网掩码的方式取决于需要划分的网络数量和主机数量。 以下是一些计算子网掩码的示例…

【LeetCode热题100】打卡第2天:两数相加

两数相加 ⛅前言 大家好&#xff0c;我是知识汲取者&#xff0c;欢迎来到我们的LeetCode热题100刷题专栏&#xff01; 精选 100 道力扣&#xff08;LeetCode&#xff09;上最热门的题目&#xff0c;适合初识算法与数据结构的新手和想要在短时间内高效提升的人&#xff0c;熟练…

【2】tensorflow基本概念及变量函数

目录 1 tensorflow运行机制 1.1 搭建计算图模型 计算图的概念 计算图的使用 新建计算图 1.2 在会话中执行计算图 会话的启动方式 1.3 指定计算图的运行设备 2 tensorflow数据模型 2.1 认识张量及属性 张量的类型 张量的阶 2.2 张量类型转换和形状变换 张量类型转换 张…