八月集训第3天解题报告

宇宙大爆炸 2022-08-03 22:30:43

1588. 所有奇数长度子数组的和

枚举长度之后枚举第一个下标和最后一个下标,加起来即可

int sumOddLengthSubarrays(int* arr, int arrSize){
    int ans = 0;
    for(int l = 0; l < arrSize; l+=2){
        for(int i = 0; i < arrSize - l; ++i){
            for(int j = i; j < arrSize && j <= i + l; ++j){
                ans += arr[j];
            }
        }
    }
    return ans;
}

可以只枚举开始和结束的下标,每次增添一个数的时候把之前的sum加入ans就不用重复枚举前面的(这个时候是按开始的下标顺序枚举的)

int sumOddLengthSubarrays(int* arr, int arrSize){
    int ans = 0;
    for(int i = 0; i < arrSize; ++i){
        int sum = 0;
        for(int j = i; j < arrSize; ++j){
            sum += arr[j];
            if((j - i + 1) & 1){
                ans += sum;
            }
        }
    }
    return ans;
}

 

1848. 到目标元素的最小距离

双指针,记录最先到达target的下标

int getMinDistance(int* nums, int numsSize, int target, int start){
    int l = start, r = start;
    int ans = INT_MAX;
    while(1){
        if(nums[l] == target){
            ans = start - l;
            break;
        }
        else if(nums[r] == target){
            ans = r - start;
            break;
        }
        else{
            if(l > 0) --l;
            if(r < numsSize - 1) ++r;
        }
    }
    return ans;
}

1652. 拆炸弹

int* decrypt(int* code, int codeSize, int k, int* returnSize){
    int* ret = (int*)malloc(sizeof(int) * codeSize);
    for(int i = 0; i < codeSize; ++i){
        ret[i] = 0;
        if(k >= 0){
            for(int j = 1; j <= k; ++j){
                if(i + j < codeSize) ret[i] += code[i + j];
                else ret[i] += code[(i + j) % codeSize];
            }
        }
        else{
            for(int j = -1; j >= k; --j){
                if(i + j >= 0) ret[i] += code[i + j];
                else ret[i] += code[i + j + codeSize];
            }
        }
    }
    *returnSize = codeSize;
    return ret;
}

 

1640. 能否连接形成数组

bool canFormArray(int* arr, int arrSize, int** pieces, int piecesSize, int* piecesColSize){
    int map[101] = {0};
    for(int i = 0; i < arrSize; ++i){
        map[arr[i]] = i + 1;//构建地址映射,因为数组中每个数都不同且大于0,可以保证这个值就是这个数
                            //的地址下标加1
    }
    for(int i = 0; i < piecesSize; ++i){
        for(int j = 0; j < piecesColSize[i]; ++j){
            if(map[pieces[i][j]] == 0){
                return false;
            }
            if(j > 0){
                int connect = map[pieces[i][j]] - map[pieces[i][j - 1]];
                //这两个数相减就是检查这两个数在arr中是否相邻
                if(connect != 1){
                    return false;
                }
            }
        }
    }
    return true;
}

 

...全文
20 回复 打赏 收藏 举报
写回复
回复
切换为时间正序
请发表友善的回复…
发表回复
发帖
万人千题

6.2w+

社区成员

学习「 算法 」的捷径就是 「 题海战略 」,社区由「 夜深人静写算法 」作者创建,三年ACM经验,校集训队队长,亚洲区域赛金牌,世界总决赛选手。社区提供系统的训练,答疑解惑,面试经验,大厂内推等机会
社区管理员
  • 英雄哪里出来
  • Amy卜bo皮
  • Risso
加入社区
帖子事件
编辑了帖子 (查看)
2022-08-05 00:35
创建了帖子
2022-08-03 22:30
社区公告

QQ群:480072171

英雄算法交流 8 群