枚举中间位置基础篇

参考资料来源灵神在力扣所发的题单,仅供分享学习笔记和记录,无商业用途。

核心思路:

**一:**直接直接用数据结构记录需要的数据,在枚举右,维护左的循环中,删除当前位置的元素即可达成一样效果

二:( 采用后缀表or其他:从后往前维护最有可能满足条件的数据结构 ),在枚举右,维护左。

**应用场景:**问题有三个下标,需要满足 0≤i<j<k<n。枚举 j,那么 i 和 k 自动被 j 隔开,互相独立,后续计算中无需关心 i 和 k 的位置关系。

模板题: 2909. 元素和最小的山形三元组 II

cpp 复制代码
class Solution {
public:
    int minimumSum(vector<int>& nums) {
        vector<int> ans(nums.size());
        ans[nums.size()-1]=nums.back();
        //后缀表:维护最有可能满足条件的数据
        for(int i=nums.size()-2;i>=2;i--) ans[i]=min(ans[i+1],nums[i]);
        int buff=nums[0],ret=INT_MAX;
        //枚举右,维护左
        for(int i=1;i<nums.size()-1;i++){
            //根据维护的左区间和后区间,判断当前元素是否满足条件
            if(buff<nums[i] && nums[i]>ans[i+1]) ret=min(ret,buff+nums[i]+ans[i+1]);
            buff=min(buff,nums[i]);
        }
        return ret==INT_MAX?-1:ret;
    }
};

力扣题单练习(灵神题单中摘取题目)

3583. 统计特殊三元组

cpp 复制代码
class Solution {
public:
    int specialTriplets(vector<int>& nums) {
        const int MOD=1E9+7;
        unordered_map<int,int> map;
        vector<int> ans(nums.size(),0);
        int ret=0;
        //后缀表:从后往前维护当前元素右侧有多少满足条件的值
        for(int i=nums.size()-1;i>=1;i--){
            ans[i]=map[nums[i]*2];
            map[nums[i]]++;
        }
        map.clear();
        map[nums[0]]++;
        //枚举右,维护左。
        for(int i=1;i<nums.size()-1;i++){
            //当前元素前面满足条件的值的数量*后缀表[i]=当前元素可以构成的特殊三元组数量
            ret=(ret+(long long)ans[i]*map[nums[i]*2])%MOD;
            map[nums[i]]++;
        }
        return ret;
    }
};

1930. 长度为 3 的不同回文子序列

**核心思路:**用位运算将字符转化成二进制记录以当前元素作为中间值的各种不同回文序列

cpp 复制代码
class Solution {
public:
    //统计以当前元素为中间值可组成的不同回文序列的数量
    int check(int x){
        int ans=0;
        for(int i=0;i<26;i++) if((x>>i) & 1) ans++;
        return ans;
    }
    用位运算将字符转化成二进制记录以当前元素作为中间值的各种不同回文序列
    int countPalindromicSubsequence(string s) {
        //题意:给定一个字符串,选取从中选取三个元素要求组成回文字符串。记录不同回文字符串的总数量
        vector<int> last(26,0),head(26,0),has(26,0);
        //数组记录后续元素
        for(int i=1;i<s.size();i++) last[s[i]-'a']++;
        for(int i=1;i<s.size()-1;i++){
            last[s[i]-'a']--;  //在后序元素数组中剔除当前元素
            head[s[i-1]-'a']++; //前序元素数组中增加当前位置的前一位的元素
            for(int j=0;j<26;j++){
                if(head[j] && last[j]){  //前后序都有的元素可组成回文序列
                    has[s[i]-'a']|=1<<j;  //记录以当前元素作为中间值的各种不同回文序列
                }
            }
        }
        int ret=0;
        for(int i=0;i<26;i++) ret+=check(has[i]);
        return ret;
    }
};

3128. 直角三角形

**核心思路:**枚举直角三角形的拐角位置

cpp 复制代码
class Solution {
public:
    long long numberOfRightTriangles(vector<vector<int>>& grid) {
        vector<int> row(grid.size()),col(grid[0].size());
        //记录每行每列有多少个1
        for(int i=0;i<grid.size();i++){
            for(int j=0;j<grid[i].size();j++){
                if(grid[i][j]==1){
                    row[i]++;
                    col[j]++;
                }
            }
        }
        long long ret=0;
        for(int i=0;i<grid.size();i++){
            for(int j=0;j<grid[0].size();j++){
                //枚举直角三角形的拐角位置,当前行-1*当前列-1=当前拐角可构成的直角三角形
                if(grid[i][j]==1) ret+=(row[i]-1)*(col[j]-1);
            }
        }
        return ret;
    }
};

2874. 有序三元组中的最大值 II

cpp 复制代码
class Solution {
public:
    long long maximumTripletValue(vector<int>& nums) {
        int n=nums.size();
        vector<int> ans(n+1,INT_MIN);
        //后缀表:从后向前维护当前最大值
        for(int i=n-1;i>=2;i--) ans[i]=max(ans[i+1],nums[i]);
        int buff=nums[0];
        long long ret=0;
        //枚举右,维护左(最大值)
        for(int i=1;i<n-1;i++){
            ret=max(ret,(long long)(buff-nums[i])*ans[i+1]);
            buff=max(buff,nums[i]);
        }
        return ret;
    }
};
相关推荐
自我陶醉@11 分钟前
计算机网络---应用层
网络·计算机网络·考研·学习方法·408·王道
烦躁的大鼻嘎1 小时前
【Linux】深入探索多线程编程:从互斥锁到高性能线程池实战
linux·运维·服务器·开发语言·c++·算法·ubuntu
今后1231 小时前
【数据结构】快速排序与归并排序的实现
数据结构·算法·归并排序·快速排序
南莺莺1 小时前
树的存储结构
数据结构·算法·
Sapphire~1 小时前
重学JS-009 --- JavaScript算法与数据结构(九)Javascript 方法
javascript·数据结构·算法
没有口袋啦1 小时前
《决策树、随机森林与模型调优》
人工智能·算法·决策树·随机森林·机器学习
小邓儿◑.◑2 小时前
贪心算法 | 每周8题(一)
算法·贪心算法
stolentime2 小时前
二维凸包——Andrew 算法学习笔记
c++·笔记·学习·算法·计算几何·凸包
Q741_1472 小时前
C++ 位运算 高频面试考点 力扣 371. 两整数之和 题解 每日一题
c++·算法·leetcode·面试·位运算
aramae2 小时前
链表理论基础
数据结构·c++·算法·leetcode·链表