六月集训(第01天) —— 数组

前言

        此为《英雄算法联盟:算法集训》的内容,具体内容详见:知识星球:英雄算法联盟 - 六月集训。加入星球后,即可享用星主 CSDN付费专栏 免费阅读 的权益。
        欢迎大家积极在评论区留言发表自己的看法,知无不言,言无不尽,养成每天刷题的习惯,也可以自己发布优质的解题报告,供社区一同鉴赏,吸引一波自己的核心粉丝。
        希望大家先自己思考,如果实在没有想法,再看下面的算法思路,如果有思路但是写不出来,可以参考朋友圈中其他人的代码,总有一款是适合你的,关注一下他,取其之长,补给之短。
        今天集训的内容是:数组
        今天的题前三题较为容易,可以瞬间秒掉,第四题需要一些实现技巧,看看谁的代码短,可以在星球里面发布动态,互相学习。

一、练习题目

题目链接难度
1588. 所有奇数长度子数组的和★☆☆☆☆
1848. 到目标元素的最小距离★☆☆☆☆
1652. 拆炸弹★☆☆☆☆
1640. 能否连接形成数组★☆☆☆☆

二、算法思路

1、所有奇数长度子数组的和

        (1)这是一个枚举的题,首先枚举起点下标 i,然后枚举终点下标 j,枚举过程中,不断进行累加,当 j - i + 1 是奇数的时候,代表数组长度为 奇数,将累加的和加到结果中即可。

class Solution {
public:
    int sumOddLengthSubarrays(vector<int>& arr) {
        int i, j;
        int ret = 0;
        for(i = 0; i < arr.size(); ++i) {
            int sum = 0;
            for(j = i; j < arr.size(); ++j) {
                sum += arr[j];
                if( (j-i+1) & 1 ) {
                    ret += sum;
                }
            }
        }
        return ret;
    }
};

2、到目标元素的最小距离

        (1)按照题目要求,找到所有值等于 target 的元素,并且用 i 和 start 相减后的绝对值,取最小的那个就是答案了。

class Solution {
public:
    int getMinDistance(vector<int>& nums, int target, int start) {
        int i, j;
        int u = -1;
        int Min = 1000000000;
        for(i = 0; i < nums.size(); ++i) {
            if(nums[i] == target && abs(i - start) < Min) {
                Min = abs(i - start);
                u = i;
            }
        }
        return Min;
    }
};

3、拆炸弹

        (1)对于每个 code[i],如果 k > 0,则从 i+1 到 i+k 去找元素进行累加,下标索引的时候,为了下标不会越界,需要对 n 进行取模;
        (2)对于每个 code[i],如果 k < 0,则从 i-1 到 i+k 去找元素进行累加,下标有可能变成负数,所以需要对 n 取模以后,再加上 n,再进行取模。原理可以参见 《夜深人静写算法(三)初等数论》 - https://blog.csdn.net/WhereIsHeroFrom/article/details/111693538 。

class Solution {
public:
    vector<int> decrypt(vector<int>& code, int k) {
        vector <int> ret;
        int n = code.size();
        int i, j, val;
        for(i = 0; i < code.size(); ++i) {
            val = 0;
            if(k > 0) {
                for(j = i + 1; j <= i + k; ++j) {
                    val += code[j % n];
                }
            }else if(k < 0) {
                val = 0;
                for(j = i - 1; j >= i + k; --j) {
                    val += code[(j % n + n) % n];
                }
            }
            ret.push_back(val);
        }
        return ret;
    }
};

4、能否连接形成数组

        (1)首先定义两个指针,一个指针指向原数组,另一个指针用于遍历 pieces 数组;
        (2)如果某一次遍历不能找到一块匹配的块,则返回 false;如果完整匹配,则原数组指针自增,当原数组指针等于数组长度时返回 true;

class Solution {
public:
    bool canFormArray(vector<int>& arr, vector<vector<int>>& pieces) {
        int i = 0, j, k;
        bool flag = false;
        while(i < arr.size()) {
            flag = false;
            for(j = 0; j < pieces.size(); ++j) {
                if(pieces[j][0] != arr[i]) {
                    continue;
                }
                for(k = 0; k < pieces[j].size(); ++k) {
                    if(pieces[j][k] == arr[i]) {
                        ++i;
                        flag = true;
                    }else {
                        return false;
                    }
                }
                if(i == arr.size()) {
                    return true;
                }
            }
            if(!flag) {
                return false;
            }
        }
        return true;
    }
};
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

英雄哪里出来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值