LeetCode 2824.统计和小于目标的下标对数目

给你一个下标从 0 开始长度为 n 的整数数组 nums 和一个整数 target ,请你返回满足 0 <= i < j < n 且 nums[i] + nums[j] < target 的下标对 (i, j) 的数目。

示例 1:

输入:nums = [-1,1,2,3,1], target = 2
输出:3
解释:总共有 3 个下标对满足题目描述:

  • (0, 1) ,0 < 1 且 nums[0] + nums[1] = 0 < target
  • (0, 2) ,0 < 2 且 nums[0] + nums[2] = 1 < target
  • (0, 4) ,0 < 4 且 nums[0] + nums[4] = 0 < target
    注意 (0, 3) 不计入答案因为 nums[0] + nums[3] 不是严格小于 target 。
    示例 2:

输入:nums = [-6,2,5,-2,-7,-1,3], target = -2
输出:10
解释:总共有 10 个下标对满足题目描述:

  • (0, 1) ,0 < 1 且 nums[0] + nums[1] = -4 < target
  • (0, 3) ,0 < 3 且 nums[0] + nums[3] = -8 < target
  • (0, 4) ,0 < 4 且 nums[0] + nums[4] = -13 < target
  • (0, 5) ,0 < 5 且 nums[0] + nums[5] = -7 < target
  • (0, 6) ,0 < 6 且 nums[0] + nums[6] = -3 < target
  • (1, 4) ,1 < 4 且 nums[1] + nums[4] = -5 < target
  • (3, 4) ,3 < 4 且 nums[3] + nums[4] = -9 < target
  • (3, 5) ,3 < 5 且 nums[3] + nums[5] = -3 < target
  • (4, 5) ,4 < 5 且 nums[4] + nums[5] = -8 < target
  • (4, 6) ,4 < 6 且 nums[4] + nums[6] = -4 < target

提示:

1 <= nums.length == n <= 50
-50 <= nums[i], target <= 50

法一:直接模拟:

class Solution {
public:int countPairs(vector<int>& nums, int target) {int sz = nums.size();int ans = 0;for (int i = 0; i < sz; ++i){for (int j = i + 1; j < sz; ++j){if (nums[i] + nums[j] < target){++ans;}}}return ans;}
};

如果nums中有n个元素,此算法时间复杂度为O(n 2 ^{2} 2),空间复杂度为O(1)。

法二:双指针法,先对nums排序,再用两个指针分别指向nums的首尾,当两指针指向的数字和小于target时,说明两指针中间的所有数字和首指针指向的数字的和都小于target,将小于target的数对的数目加到结果上,此时我们有两个选择,一是自增首指针,二是自减尾指针,由于我们把首尾指针之间所有数字和首指针指向的数字的数对的数目都加上了,相当于自减尾指针的结果也已经计算过了,因此要自增首指针;如果两指针指向的数字和大于等于target,那么首尾指针之间的所有数字和尾指针指向的数字的和也都大于target,因此要自减尾指针:

class Solution {
public:int countPairs(vector<int>& nums, int target) {int begin = 0;int end = nums.size() - 1;quickSort(nums, begin, end);int res = 0;while (begin < end){if (nums[begin] + nums[end] < target){res += end - begin;++begin;}else{--end;}}return res;}private:void quickSort(vector<int> &nums, int begin, int end){if (begin >= end){return;}int mid = (begin + end) / 2;swap(nums[mid], nums[end]);int bound = begin - 1;for (int i = begin; i <= end - 1; ++i){if (nums[i] < nums[end]){++bound;swap(nums[bound], nums[i]);}}swap(nums[bound + 1], nums[end]);quickSort(nums, begin, bound);quickSort(nums, bound + 2, end);}
};

此算法时间复杂度为O(nlogn),空间复杂度为O(logn)。

法三:二分法,先对nums排序,之后遍历nums中的每个元素,对于每个元素i,二分法找该元素后面的符合题目的最大元素m,m和i之间所有数字都可以与i组成符合题意的数对:

class Solution {
public:int countPairs(vector<int>& nums, int target) {int begin = 0;int end = nums.size() - 1;quickSort(nums, begin, end);int res = 0;for (int i = 0; i <= end; ++i){res += binarySearch(nums, i, target - nums[i]) - i;}return res;}private:int binarySearch(vector<int> nums, int begin, int subtraction){int end = nums.size() - 1;int result = begin;while (begin <= end){int mid = begin + (end - begin) / 2;if (nums[mid] < subtraction){result = mid;begin = mid + 1;}else{end = mid - 1;}}return result;}void quickSort(vector<int> &nums, int begin, int end){if (begin >= end){return;}int mid = (begin + end) / 2;swap(nums[mid], nums[end]);int bound = begin - 1;for (int i = begin; i <= end - 1; ++i){if (nums[i] < nums[end]){++bound;swap(nums[bound], nums[i]);}}swap(nums[bound + 1], nums[end]);quickSort(nums, begin, bound);quickSort(nums, bound + 2, end);}
};

此算法时间复杂度为O(nlogn),空间复杂度为O(logn)。

法四:前缀和,可将nums中的元素作为key,元素出现的数量为value,组合出一个数字出现频率的数组,然后计算该数组的前缀和,此时该前缀和数组中某一元素的含义变为,小于等于该元素的key的数字的个数,然后遍历nums,找出小于目标数字的个数。对于一对符合题意的数对,此方法会计数两次,因此最后要将结果除2:

class Solution {
public:int countPairs(vector<int>& nums, int target) {vector<int> prefixSum(101);for (int num : nums){++prefixSum[num + 50];}for (int i = 1; i < prefixSum.size(); ++i){prefixSum[i] += prefixSum[i - 1];}int ans = 0;for (int num : nums){// 如果目标数字小于0,就跳过,因为这时说明要找的数字小于-50,不存在if (target - num + 49 < 0){continue;}// 如果目标数字大于100,按最大的数算,因为下标最多只到100if (target - num + 49 > 100){ans += prefixSum[100];}else{ans += prefixSum[target - num + 49];}// 如果num本身也符合目标数字,则去掉自身if (num * 2 < target){--ans;}}return ans / 2;}
};

如果nums的长度为n,每个元素的范围为m,此方法时间复杂度为O(n+m),空间复杂度为O(m)。

法五:树状数组可以更高效地计算前缀和,树状数组每次更新前缀和的时间复杂度为O(lgn),计算前缀和的时间复杂度也是O(lgn),原理是按二进制的每一位来计算前缀和,比如前11个数字的前缀和,11的二进制为1011,我们就可以把1010-1011区间的前缀和、1000-1010区间的前缀和、0000-1000区间的前缀和加起来,这样最多是对数级别的时间复杂度:

class Solution {
public:int countPairs(vector<int>& nums, int target) {tree.resize(151);int ans = 0;for (int num : nums){ans += query(target - num + 49);add(num + 50, 1);}return ans;}private:vector<int> tree;int query(int n){++n;int ans = 0;for (int i = n; i > 0; i -= lowbit(i)){ans += tree[i];}return ans;}void add(int n, int add){++n;for (int i = n; i <= tree.size(); i += lowbit(i)){tree[i] += add;} }// 求x二进制表示中,最后一位二进制1表示的值int lowbit(int x){return x & (-x);}
};

如果nums的长度为n,target和nums的长度之和为m,此方法时间复杂度为O(nlgm),空间复杂度为O(m)。

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

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

相关文章

全网最详细的从0到1的turbo pnpm monorepo的前端工程化项目[搭建篇]

全网最详细的从0到1的turbo pnpm monorepo的前端工程化项目[搭建篇] 引言相关环境技术栈初始化工程安装turbo配置pnpm-workspace安装husky安装lint-staged安装eslint安装prettier配置 .editorconfig配置 .gitignore初步项目结构结语 引言 最近各种原因&#xff0c;生活上的&am…

代码随想录算法训练营第三十四天|860.柠檬水找零、406.根据身高重建队列、452.用最少数量的箭引爆气球

860.柠檬水找零 public class Solution {public bool LemonadeChange(int[] bills) {int cnt50;int cnt100;for(int i0;i<bills.Length;i){if(bills[i]5){cnt5;}else if(bills[i]10){cnt5--;cnt10;}else if(cnt10!0){cnt5--;cnt10--;}else{cnt5-3;}if(cnt5<0){return fa…

SSTI模板注入漏洞(vulhub 复现)

首先了解模板引擎&#xff1a; 模板引擎&#xff08;这里特指用于Web开发的模板引擎&#xff09;是为了使用户界面与业务数据&#xff08;内容&#xff09;分离而产生的&#xff0c;它可以生成特定格式的文档&#xff0c;利用模板引擎来生成前端的html代码&#xff0c;模板引擎…

2024年华为OD机试真题-求最多可以派出多少支团队-Python-OD统一考试(C卷)

题目描述&#xff1a; 用数组代表每个人的能力&#xff0c;一个比赛活动要求参赛团队的最低能力值为N&#xff0c;每个团队可以由1人或2人组成&#xff0c;且1个人只能参加1个团队&#xff0c;请计算出最多可以派出多少支符合要求的团队&#xff1f; 输入描述&#xff1a; 5 3 …

网络原理 - HTTP/HTTPS(1)

HTTP HTTP是什么 HTTP("全程超文本协议")是一种应用非常广泛的应用层协议. 文本:字符串(能在utf8/gbk)码表上找到合法字符. 超文本:不仅是字符串,还能携带图片啥的(HTML). 富文本:类似于word文档这种. HTTP诞生于1991年.目前已经发展为最主流使用的一种应用层协议.…

服务端和客户端以及前后端相关概念区分

服务端和客户端以及前端和后端是两组相关但不完全相同的概念。 一、服务端&#xff08;Server-side&#xff09;和客户端&#xff08;Client-side&#xff09; 服务端和客户端是指在分布式系统或网络应用中相对的两个部分。是指在计算机网络中不同角色的两个主要实体。 服务端…

如何使用python 挑战将ai生成的概念图制作成2d游戏

要使用Python将AI生成的概念图制作成2D游戏&#xff0c;你可以遵循以下步骤&#xff1a; 生成概念图&#xff1a; 使用AI图像生成工具&#xff08;如DALL-E、DeepArt等&#xff09;来创建你的游戏概念图。保存生成的图像文件&#xff0c;通常为PNG或JPEG格式。 选择游戏引擎&a…

truncate、delete、drop的区别?

truncatedeletedrop操作类型DDLDMLDDL支持回滚不支持支持 不支持 删除内容 删除表中所有数据&#xff0c;保留表结构删除表全部或者一部分数据行&#xff0c;保留表结构从数据库中删除表&#xff0c;所有数据行&#xff0c;索引和权限也会被删除删除速度速度快速度慢&#xff…

python中怎么画对数坐标图

在Python中&#xff0c;我们可以使用matplotlib库来创建对数坐标图。以下是一个基本的示例&#xff0c;展示了如何在x轴和y轴上使用对数尺度&#xff1a; python复制代码 import matplotlib.pyplot as plt import numpy as np # 创建一些数据 x np.linspace(0.1, 10, 100) y …

【状态估计】深度传感器与深度估计算法(1/3)

深度传感器与深度估计算法 深度传感器概念 获得空间中目标位置或距离的传感器&#xff0c;按接收的媒介波来源可分为主动式和被动式两大范畴&#xff0c;主动式包括激光雷达、雷达、超声波传感器等&#xff0c;被动式主要为单目、多目相机等&#xff0c;同时两大类可组合为混…

防火墙 iptables(二)-------------SNAT与DNAT

一、SNAT ①SNAT 应用环境: 局域网主机共享单个公网IP地址接入Internet (私有IP不能在Internet中正常路由) ②SNAT原理: 源地址转换&#xff0c;根据指定条件修改数据包的源IP地址&#xff0c;通常被叫做源映射 数据包从内网发送到公网时&#xff0c;SNAT会把数据包的源IP由…

卷积神经网络吴恩达coursera

Convolutional NN Foundations of CNN matrixs convolution Edge detection Vertical / horizontial conv-forward(tf.nn.cov2d) m a t r i x ( 6 6 ) ∗ f i l t e r ( 3 3 ) m a t r i x ( 4 4 ) matrix(6\times6)*filter(3\times3)matrix(4\times4) matrix(66)∗fi…

【Java EE初阶十九】网络原理(四)

4. 数据链路层 数据链路层也有很多种协议&#xff0c;其中一个比较常见常用的,就是“以太网协议”&#xff08;通过网线/光纤, 来通信所使用的协议叫做以太网协议&#xff0c;以太网是横跨数据链路层 物理层&#xff09;&#xff1b; 4.1 以太网数据帧格式 帧头 载荷(IP 数据…

从一到无穷大 #24 LogReducer:讨论日志中热点的影响,识别及在线解决方法

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言LogReducer系统性分析日志影响&#xff0c;原因在线日志缩减框架 反省总结 引言 …

提升起重机效率与降低维修成本:PreMaint预测性维护系统的应用

随着科技的不断发展&#xff0c;人工智能技术在各行各业都展现出了强大的应用潜力。在港口起重机设备的维护管理中&#xff0c;预测性维护系统是一项革命性的技术&#xff0c;为提升设备效率、降低维修成本提供了全新的解决方案。本文将深入探讨起重机预测性维护系统的原理、应…

nvm的相关属性以及用法

一、安装nvm的原因 nvm是一个命令行工具&#xff0c;用于管理和切换到不同版本的 Node.js。 二、安装nvm&#xff08;node 版本管理工具&#xff09; 1、注意&#xff1a; Windows 不支持 NVM&#xff0c;因为 NVM 仅在 Linux 和 Mac 上受支持。你将在 Windows 机器上使用的…

如何优化静态服务器以提高网站速度?

随着互联网的发展&#xff0c;网站的速度成为了用户体验的重要因素之一。一个快速、响应迅速的网站能够提高用户的满意度和忠诚度&#xff0c;同时也能增加搜索引擎优化&#xff08;SEO&#xff09;的效果。因此&#xff0c;优化静态服务器以提高网站速度是每个站长必须关注的问…

LeetCode2435. Paths in Matrix Whose Sum Is Divisible by K——动态规划

文章目录 一、题目二、题解 一、题目 You are given a 0-indexed m x n integer matrix grid and an integer k. You are currently at position (0, 0) and you want to reach position (m - 1, n - 1) moving only down or right. Return the number of paths where the su…

计算机视觉所需要的数学基础

计算机视觉领域中使用的数学知识广泛而深入&#xff0c;以下是一些关键知识点及其在计算机视觉中的应用&#xff1a; 线性代数&#xff1a; - 矩阵运算&#xff1a;用于图像的表示和处理&#xff0c;如图像旋转、缩放、裁剪等。 - 向量空间&#xff1a;用于描述图像中的…

中小品牌项目管理软件排行榜:发现行业新秀与潜力股

使用项目管理软件可以帮助企业提高工作效率&#xff0c;降低成本&#xff0c;提升竞争力。在项目管理软件中&#xff0c;不仅有大品牌如Zoho Projects、Microsoft Project、Jira等&#xff0c;还有一些小品牌的软件也备受关注。本文就为大家介绍在项目管理软件排行榜中小品牌榜…