比賽地址 :
?競賽 - 力扣 (LeetCode)
t1
: 直接暴力即可
class Solution {
public:int countTestedDevices(vector<int>& b) {int n = b.size();int ans = 0;for(int i=0;i<n;i++){if(b[i]>0){ans ++;for(int j=i+1;j<n;j++){b[j] = max(b[j]-1,0);}}}return ans;}
};
t2 :?
需要用到快速冪
typedef long long LL;
class Solution {
public:LL qmi(int m,int k,int p){int res = 1 % p,t =m;while(k){if(k&1) res = res * t % p ;t = t * t % p;k >>= 1;}return res;}vector<int> getGoodIndices(vector<vector<int>>& vs, int target) {int n = vs.size();vector<int> ans;// ((aibi % 10)ci) % mi == targetfor(int i=0;i<n;i++){int a = vs[i][0],b=vs[i][1],c=vs[i][2],m=vs[i][3];if( qmi(qmi(a,b,10),c,m) == target){ans.push_back(i);}}return ans;}
};
t3
滑動窗口 : 維護一個窗口( l?, r ) 使其中的最大值出現的次數為k次,小于k的時候,r向后遍歷,直到出現次數==k,這時候,刪除窗口左邊的數字,使最大值出現次數<k,然后這樣循環遍歷即可;
class Solution {
public:long long countSubarrays(vector<int>& nums, int k) {long long ans = 0;int n = nums.size();int l = 0 , r = 0 ;int ma = *max_element(nums.begin(),nums.end());int t = 0 ;// 統計窗口中ma出現的次數while(r < n){t += nums[r] == ma;while(t==k){t -= nums[l++]==ma;}ans += l ; // 以r為右端點的,以l為左端點的,那么l之前的都可以(能夠很好的去重)r ++ ; } return ans ;}
};
t4:
首先重復元素肯定只能夠出現在一個數組里面,那么就可以使用類似于lc56區間合并的思想了,具體實現請看代碼 :?
const int mod = 1e9+7;
class Solution {
public:int numberOfGoodPartitions(vector<int>& nums) {// 每個重復元素必須選擇 , 然后類似區間合并unordered_map<int,pair<int,int>> mp;int n = nums.size();for(int i=0;i<n;i++) // 找出每個數字的首尾地址if(mp.find(nums[i])==mp.end()) // 之前沒有出現過mp[nums[i]] = {i, i} ;else{ // 之前出現過mp[nums[i]].second = i; }vector<pair<int,int>> a;for(auto &[_,p]:mp) a.push_back(p);sort(a.begin(),a.end(),[](const auto &p,const auto &q){return p.first < q.first ; // 按區間的左端點排序});// 下面就是合并區間的思想了,看下能夠最多分成 m 個區間// ans = 2 ^ (m - 1) int ans = 1; // 最少就是整個數組的一種選法int idx = a[0].second;for(int i=1;i<a.size();i++){int l = a[i].first , r = a[i].second;if(l>idx){// 新開一個區間ans = ans * 2 % mod;} idx = max(idx , r);}return ans;}
};