跟着英雄哥6月集训——6.1
文章目录
题目链接:
六月一日数组题目
1588. 所有奇数长度子数组的和
1848. 到目标元素的最小距离
1652. 拆炸弹
1640. 能否连接形成数组
一、1588. 所有奇数长度子数组的和
1.暴力循环:
class Solution {
public:
int sumOddLengthSubarrays(vector<int>& arr) {
int ans = 0;
int n = arr.size(); //数组长度
for(int start = 0; start < n; start++){ //start是子数组的开始下标
for(int len = 1; len + start <= n; len += 2){//len + start <= n是为了防止下标越界
//len 是子数组的长度,最小是1,因为是奇数所以长度每次是+2
int end = len + start - 1;//子数组结束下标
for(int i = start; i <= end; i++){
ans += arr[i];
}
}
}
return ans;
}
};
2.前缀和:
什么是前缀和?
有一个数组A,有个数组prefixSums,prefixSums[i+1] = prefixSums[i] + a[i].
数组prefixSums的第i+1项就是数组A的前i项和,这就是前缀和
class Solution {
public:
int sumOddLengthSubarrays(vector<int>& arr) {
//start是子数组的开始下标
//len 是子数组的长度,最小是1
//子数组结束下标
int ans = 0;
int n = arr.size();
vector<int> prefixSums(n+1);
prefixSums[0] = 0;
for(int i = 0; i < n; i++){
prefixSums[i+1] = prefixSums[i] + arr[i];
}//由前缀和的概念可知,prefixSums[i+1]代表arr前i项和
for(int start = 0; start < n; start++){
for(int len = 1; len + start <= n; len += 2){
int end = len + start - 1;
ans += prefixSums[end + 1] - prefixSums[start];
}
}//用前end项的和 减去 前start项的和就是end-start项的和即中间那些奇数子数列的和。
return ans;
}
};
二、1848. 到目标元素的最小距离
1.就特别简单:
class Solution {
public:
int sumOddLengthSubarrays(vector<int>& arr) {
int ans = 0;
int n = arr.size(); //数组长度
for(int start = 0; start < n; start++){ //start是子数组的开始下标
for(int len = 1; len + start <= n; len += 2){//len + start <= n是为了防止下标越界
//len 是子数组的长度,最小是1,因为是奇数所以长度每次是+2
int end = len + start - 1;//子数组结束下标
for(int i = start; i <= end; i++){
ans += arr[i];
}
}
}
return ans;
}
};
三、1652. 拆炸弹
1.循环数组用取余:
class Solution {
public:
vector<int> decrypt(vector<int>& code, int k) {
int n = code.size();
int i;
vector<int> vec(n);
for(i = 0; i < n; i++){
int sum = 0;
if( k > 0){
for(int j = i + 1; j <= i + k; j++){
sum += code[j % n];
}
}
else if(k < 0){
for(int j = i - 1; j >= i + k; j--){
sum += code[(j + n) % n];
}
}
vec[i] = sum;
}
return vec;
}
};
四、1640. 能否连接形成数组
1.非常简单的思路:
学习大佬的解题
class Solution {
public:
bool canFormArray(vector<int>& arr, vector<vector<int>>& pieces) {
int Map[101] = {0};
for(int i = 0; i < arr.size(); i++){
Map[arr[i]] = i + 1;
}
for(int i = 0; i < pieces.size(); i++){
for(int j = 0; j < pieces[i].size(); j++){
if( Map[pieces[i][j]] == 0 ){
return false;
}
if( j > 0 ){
int x = Map[pieces[i][j]] - Map[pieces[i][j - 1]];
if (x != 1){
return false;
}
}
}
}
return true;
}
};
总结
从三月加入英雄哥的挑战百日早起刷题,到现在就看过了三次五点直播,大学的课程还是太紧张了,而且室友都在,不容易起床。现在放假了,开始5点早起看英雄哥直播,整理每天的题目(多借鉴大佬,我太菜)。今天是第一天,加油,坚持六月集训!!!