计数类双指针总结
admin
2024-02-23 23:23:44
0

核心思路

一般是求子数组的问题。

双/三指针的计数问题一般是:对于每一个右边界,找到满足条件的左边界。对于不满足的条件的边界加上一个标志。对于满足条件的边界,需要加上一个标志。

例题

leetcode 2444. 统计定界子数组的数目

题解

  • 代码
class Solution {public long countSubarrays(int[] nums, int minK, int maxK) {var ans = 0L;int n = nums.length, minI = -1, maxI = -1, i0 = -1;for (var i = 0; i < n; ++i) {var x = nums[i];if (x == minK) minI = i;if (x == maxK) maxI = i;if (x < minK || x > maxK) i0 = i; // 子数组不能包含 nums[i0]ans += Math.max(Math.min(minI, maxI) - i0, 0);}return ans;}
}

795. 区间子数组个数

方法一:一次遍历
思路与算法

一个子数组的最大值范围在$ [left,right]表示子数组中不能含有大于表示子数组中不能含有大于表示子数组中不能含有大于right的元素,且至少含有一个处于的元素,且至少含有一个处于的元素,且至少含有一个处于[left, right]$区间的元素。

我们可以将数组中的元素分为三类,并分别用 000, 111, 222 来表示:

  1. 小于leftleftleft,用 000 表示;
  2. 大于等于 leftleftleft且小于等于 rightrightright,用 111 表示;
  3. 大于 rightrightright,用 222 表示。

那么本题可以转换为求解不包含 222,且至少包含一个 111 的子数组数目。我们遍历 iii,并将右端点固定在 iii,求解有多少合法的子区间。过程中需要维护两个变量:

last1last1last1: 表示上一次 111 出现的位置,如果不存在则为 −1-1−1;
last2last2last2: 表示上一次 222 出现的位置,如果不存在则为 −1-1−1。
如果 last1≠−1last1≠−1last1​=−1

那么子数组若以 iii 为右端点,合法的左端点可以落在 (last2,last1](last2,last1](last2,last1]之间。这样的左端点共有 last1−last2last1−last2last1−last2 个。因此,我们遍历 iii:

如果 left≤nums[i]≤rightleft≤ nums[i]≤rightleft≤nums[i]≤right,令 last1=ilast1 = ilast1=i
否则如果 nums[i]>rightnums[i]>rightnums[i]>right令 last2=ilast2=ilast2=i
然后将last1−last2last1−last2last1−last2

累加到答案中即可。最后的总和即为题目所求。

class Solution {public int numSubarrayBoundedMax(int[] nums, int left, int right) {int res = 0, last2 = -1, last1 = -1;for (int i = 0; i < nums.length; i++) {if (nums[i] >= left && nums[i] <= right) {last1 = i;} else if (nums[i] > right) {last2 = i;last1 = -1;}if (last1 != -1) {res += last1 - last2;}}return res;}
}

Problem: 2488. 统计中位数为 K 的子数组

这个题目的想法来源于795. 区间子数组个数

  1. 首先,大于他的就设成1, 小于他的就设成-1。
    这样问题就变成了求包含0的子数组,并且子数组的和为0或者1的子数组的个数。

  2. 其次,使用双指针的思想,对于包含k之后的元素,每一个作为数组的终点的话,前面有多少个点可以作为起点。这样就可以使用前缀和 + hash的进行求解。

求前缀和,使用hash统计k之前的数组中前缀和的种类,以及每一种的个数。
最后对于k之后的数组元素,统计前缀和中等于或者比当前前缀和小1的起点个数,也就是种类个数。也就是说,如果当前作为终点,有多少起点可以让前缀和为0或者1

  • Code
class Solution {
public:int countSubarrays(vector& nums, int k) {unordered_mapmp;int n = nums.size();int sum[n + 1];sum[0] = 0;mp[0] = 1;int flag = 0;int ans = 0;for (int i = 0; i < n; i++) {int add = nums[i] > k ? 1 : (nums[i] == k ? 0 : -1);sum[i + 1] = sum[i] + add;   if (add == 0) flag = 1;if (!flag) mp[sum[i + 1]] ++;else ans += mp[sum[i + 1]] + mp[sum[i + 1] - 1];}return ans;}
};

相关内容

热门资讯

安卓系统的移动加密软件,安全守... 你知道吗?在这个信息爆炸的时代,保护个人隐私变得尤为重要。而手机,作为我们日常生活中不可或缺的伙伴,...
最低安卓系统淘汰时间,揭秘最低... 你知道吗?在科技飞速发展的今天,手机更新换代的速度简直就像坐上了火箭!这不,最近有个话题在数码圈里炒...
安卓系统什么框架好用,探索最佳... 你有没有想过,你的安卓手机里那些应用,是怎么运行得那么顺畅的呢?其实,这背后可是有“大功臣”的——那...
平板安卓系统和ios,安卓与i... 你有没有发现,现在身边的朋友几乎人手一台平板电脑呢?无论是追剧、办公还是游戏,平板电脑都成了我们生活...
安卓的定位系统叫什么,GPS导... 你有没有想过,你的手机是怎么知道你在哪儿的呢?是不是觉得这事儿很神奇?其实,这背后有一个强大的技术支...
老式电视安卓系统升级,解锁智能... 你有没有发现,家里的老式电视突然变得聪明起来啦?没错,就是那个陪伴我们多年的老伙伴,它竟然悄悄地升级...
长安车载系统升级安卓 你有没有发现,最近你的长安车好像变得聪明多了?没错,就是那个车载系统,它悄悄地进行了安卓升级,简直就...
安卓系统损坏标志图,故障原因与... 手机突然间闹起了脾气,屏幕上那个安卓系统损坏的标志图,简直就像是个不速之客,突然闯进了你的生活。别急...
安卓系统自带投屏,轻松实现多屏... 你是不是也和我一样,有时候想把自己的手机屏幕上的内容分享给朋友或者家人看,但又觉得用数据线连接太麻烦...
mac可以下安卓系统么 亲爱的果粉们,你是否曾有过这样的疑问:Mac可以下安卓系统吗?这个问题,不仅让你我好奇,也让不少科技...
diy主机安卓系统推荐 亲爱的DIY爱好者们,你是否曾梦想过拥有一台完全由自己组装的安卓主机?想象一台运行流畅、功能强大的安...
安卓13系统可以安装吗 你有没有听说安卓13系统已经发布了?是不是迫不及待想要升级你的手机,体验一下新系统的魅力呢?不过,在...
手机壳平价推荐安卓系统,时尚与... 手机壳可是咱们手机的最佳守护者呢!想象你的宝贝手机在日常生活中难免会遭遇各种“小意外”,有了手机壳,...
麦芒是安卓系统吗,深度解析安卓... 你有没有想过,手机里的那个麦芒,它是不是安卓系统呢?这个问题,估计不少手机控都好奇过吧!今天,就让我...
苹果x系统感觉像安卓,安卓风潮... 你有没有发现,最近苹果的X系统好像有点儿像安卓呢?是不是觉得苹果的“高贵”形象突然变得有点儿接地气了...
小米的安卓系统设置在哪,轻松生... 你有没有发现,小米手机的操作界面简洁又美观,功能强大到让人爱不释手?但是,有时候你可能会觉得,这个设...
安卓系统荣耀排第一,引领智能手... 你知道吗?在智能手机的世界里,有一个系统可是风头无两,那就是安卓系统!而在这众多安卓手机品牌中,有一...
充电宝带安卓系统,便携式智能电... 你有没有想过,你的充电宝也能拥有自己的操作系统呢?没错,就是安卓系统!听起来是不是很酷?想象你的充电...
安卓类原生系统手机推荐,精选原... 你有没有想过,拥有一部安卓类原生系统手机,就像是拥有了掌控自己世界的魔法棒?没错,原生系统带来的流畅...
努比亚安卓13系统下载,下载与... 你有没有听说?努比亚手机最近可是大动作连连呢!他们推出了全新的安卓13系统,而且现在就可以下载啦!是...