力扣周赛248期(下)

279 阅读2分钟

这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战

1921. 消灭怪物的最大数量

S4}X7H.png

GC45F~74037LZUAIW6QURE.png

思路分析

抛掉速度的存在,这道题变得不能更简单,每次消灭数字最小的怪物就可以了。那么考虑速度,其实就是从路程的最近改为时间的最短,重新计算排序,最后还是消灭数字最小的怪物

考虑下边界条件,这题感觉就是个卡五分钟的题,

代码

int eliminateMaximum(vector<int>& dist, vector<int>& speed) {
    vector<double> vec;
    for(int i = 0 ; i < dist.size(); i++ ){
        vec.push_back((double)dist[i]/(double)speed[i]);
    }
    sort(vec.begin(), vec.end());
    int t = 1;
    while(t < vec.size()){
        if (t >= vec[t]){
            return t;
        }
        t++;
    }
    return vec.size();
}

1923. 最长公共子路径

ML4)MP.png

思路分析

遇到题不会就穷举再想办法剪枝。

穷举就不用详细说了。

由于当存在最长公共子路径长度为len的时候,一定会存在公共子路径len-1,因此我们可以通过二分查找的方式来找到len值。那么,在已知长度为len的情况下,怎么判断是否存在公共子路径。

已知path[0]具有的子路径集合为set0,那么我们求set0...setn的并集就可以了,不过实际操作上我们知道并操作是一假则假,因此我们可以在set0的前提下,如果某路径不存在,则不是公共路径,如果遍历一个集合后,set0某个元素未被访问,则set0减去该元素。

现在问题从在已知长度为len的情况下,怎么判断是否存在公共子路径。 转换为 如何判断某元素是否存在,因为如果是数组的话会导致判断元素是否存在的时间复杂度过长,因此我们可以尝试将数组转换为字符串的方式存储key值。

但是,不断地处理字符串其实还是比较麻烦的,经查询答案,我们发现答案使用了滚动哈希的办法,说是滚动哈希,其实就是使用数字作为hash的key值。

数字数组如何转化为数字呢,这个就是十分常见的转化为n进制,(而n进制的n也作为参数给你了!!十分经典的谜底在谜面上,竟然没有注意到!)而这带来的一个好处就是可以根据第i个子数组来计算第i+1个子数组,

这里官方题解给了一个很像无穷级数的递推公式,虽然是正确的,但是其实杀鸡焉用宰牛刀

其实这个很简单,

已知,长度为len,以i为起点,n进制转化数字K那么长度为len+1,以i为起点,n进制转化数字是Kn+arr[len+1]而这个数字相对于最终结果是多了个最高位的,所以结果为Kn+arr[len+1]arr[i]nlen 已知,长度为len,以i为起点,n进制转化数字K, \\那么长度为len+1,以i为起点,n进制转化数字是 K * n + arr[len+1] \\ 而这个数字相对于最终结果是多了个最高位的,所以结果为 K * n + arr[len+1] - arr[i] * n^{len}