《算法集训传送门》
👉引言
铭记于心 | ||
---|---|---|
🎉✨🎉我唯一知道的,便是我一无所知🎉✨🎉 |
💖
❄️我们的算法之路❄️💖
众所周知,作为一名合格的程序员,算法 能力 是不可获缺的,并且在算法学习的过程中我们总是能感受到算法的✨魅力✨。
☀️🌟短短几行代码,凝聚无数前人智慧;一个普通循环,即是解题之眼🌟☀️
💝二分,💝贪心,💝并查集,💝二叉树,💝图论,💝深度优先搜索(dfs),💝宽度优先搜索(bfs),💝数论,💝动态规划等等, 路漫漫其修远兮,吾将上下而求索! 希望在此集训中与大家共同进步,有所收获!!!🎉🎉🎉
今日主题:前缀和
- 前缀和一般是与 (哈希表、二分、双指针)等结合使用,以优化时间复杂度,很少单独考察
👉⭐️第一题💎
✨题目
✨思路:
先求出数组的前缀和,然后当第i个元素为中心坐标时,那么前i-1个元素一定是S[n-1]-nums[i]的1/2,注意需要单独将最左侧为中心坐标的情况单独拿出来
✨代码:
class Solution {
public:
int pivotIndex(vector<int>& nums) {
int n = nums.size();
vector<int>S(n);
S[0] = nums[0];
for (int i = 1; i <n ; i++) {
S[i]=nums[i] + S[i - 1];
}
int end = S[n - 1];
if(!(end-nums[0])) return 0;
for (int i = 1; i < n; i++) {
int te = end-nums[i];
if (te == 2 * S[i - 1]) {
return i;
}
}
return -1;
}
};
👉⭐️第二题💎
✨题目
✨思路:
哈希表+统计个数
✨代码:
class Solution {
public:
int subarraysDivByK(vector<int>& nums, int k) {
unordered_map<int, int> record = {{0, 1}};
int sum = 0, ans = 0;
for (int elem: nums) {
sum += elem;
int modulus = (sum % k + k) % k;
if (record.count(modulus)) {
ans += record[modulus];
}
++record[modulus];
}
return ans;
}
};
👉⭐️第三题💎
✨题目
✨思路:
前缀和与最长子数组进行求解
✨代码:
class Solution:
def countSubarrays(self, nums: List[int], k: int) -> int:
size=len(nums)
sum=[0]*(size+1)
for i,v in enumerate(nums):
sum[i+1]=sum[i]+v
count=0
st=0
ed=1
while st<size:
while ed<=size:
if (sum[ed]-sum[st])*(ed-st)<k:
count+=ed-st
ed+=1
else:
break
st+=1
return count
👉⭐️第四题💎
✨题目
✨思路:
通过推理可知,先排序,然后只需比较第i与i+n个元素的差是否至少比x大即可,因为排序之后这种一一对应的位置排放恰恰是可以让相应的差值最大的情况
✨代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
while (n--)
{
int m, tar;
cin >> m >> tar;
int sum = 2 * m;
vector<int> nums(sum);
for (int i = 0; i < sum; i++)
{
cin >> nums[i];
}
int t = 1;
sort(nums.begin(), nums.end());
for (int i = 0; i < m; i++)
{
if ((nums[i + m] - nums[i]) < tar)
{
t = 0;
break;
}
}
if (t)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
system("pause");
return 0;
}
写在最后:
相信大家对今天的集训内容的理解与以往已经有很大不同了吧,或许也感受到了算法的魅力,当然这是一定的,路漫漫其修远兮,吾将上下而求索!伙伴们,明天见!
、