2763. 所有子数组中不平衡数字之和
思路:第一层for循环遍历子数组的左端点i,第二层for循环遍历子数组的右端点j,同时用状态数组sta记录区间[i,j]元素出现的情况。
在第二层for循环遍历时,如果当前右端点nums[j]出现过,那么在这段子数组排序完后,和先前“出现过的点”的效果是一样的,接着遍历右端点即可。
如果当前右端点nums[j]没有出现过,那就可以进行讨论:判断nums[j]+1和nums[j]+1出现的情况。
1:两个都没有出现,那么cnt+1;
2:有一个出现,那么cnt不变;(相当于新产生的不平衡数字抵消了另外一种情况:破坏了“出现的那个元素”产生的不平衡数字,)
3:两个都出现,那么cnt-1;(相当于在这两个数之间插入了nums[j],那么没产生新的同时还破坏了旧的)
class Solution {
public:
int sumImbalanceNumbers(vector<int>& nums) {
int n=nums.size();
bool sta[1010];
int ans=0;
//第一层for循环遍历的是子数组的左端点
for(int i=0;i<n;i++){
//记录当前区间[i,j]的不平衡数字之和
int cnt=0;
//记录当前区间[i,j]元素出现的情况
memset(sta,0,sizeof sta);
//标记左端点
sta[nums[i]]=1;
//第二层for循环遍历的是子数组的右端点
for(int j=i+1;j<n;j++){
//如果当前右端点出现过,那么在排序完后,和先前“出现过的点”的效果是一样的
//如果当前右端点没有出现过,那就可以进行讨论
if(!sta[nums[j]]){
sta[nums[j]]=1;
cnt+=1-sta[nums[j]-1]-sta[nums[j]+1];
}
//这里是记录区间[i,j]的不平衡数字之和
ans+=cnt;
}
}
return ans;
}
};