参考资料来源灵神在力扣所发的题单,仅供分享学习笔记和记录,无商业用途。
核心思路:
一:直接直接用数据结构记录需要的数据,在枚举右,维护左的循环中,删除当前位置的元素即可达成一样效果
二:(采用后缀表or其他:从后往前维护最有可能满足条件的数据结构 ),在枚举右,维护左。
应用场景:问题有三个下标,需要满足 0≤i<j<k<n。枚举 j,那么 i 和 k 自动被 j 隔开,互相独立,后续计算中无需关心 i 和 k 的位置关系。
模板题:2909. 元素和最小的山形三元组 II
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. 统计特殊三元组
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 的不同回文子序列
核心思路:用位运算将字符转化成二进制记录以当前元素作为中间值的各种不同回文序列
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. 直角三角形
核心思路:枚举直角三角形的拐角位置
class Solution {
public:long long numberOfRightTriangles(vector<vector<int>>& grid) {vector<int> row(grid.size()),col(grid[0].size());//记录每行每列有多少个1for(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
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;}
};