力扣周赛第253期

259 阅读1分钟

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

1961. 检查字符串是否为数组前缀

截屏2021-08-19 下午9.57.30.png

思路分析

这道题坑还是挺多的,最开始以为可以将words变为一个长字符串,只要slong.find(s) == 0,那就说明字符串s成为words的前缀字符串。

但是这种方法处理不了如下情况

"a"

["aa","aaaa","banana"]

后来采用tmp记录s的游标,二重循环遍历words:

for(int i = 0; i < words.size(); i++){
    for(int j = 0 ; j < words[i].size(); j++){
        if (tmp < n){
            if (words[i][j] != s[tmp++]){
                return false;
            }
        }else{
            if(j == 0){

            return true;
            }
            return false ;
        }
    }
}

如果tmp == n的时候,判断是否是遍历了一个完整的数组,跳出循环的时候,再判断一次是否遍历完成(排除下字符串s远远大于words的情况)

1962. 移除石子使总数最小

截屏2021-08-19 下午10.28.33.png

思路分析

答案要求我们返回石子的最小总数,而每次操作是将一个数/2,所以这道题大体上的思路一定是贪心,通过这种方式让我们最后获得石子的最小总数,那么最简单的实现方式就是遍历,通过k次for循环,每次找到石子最大值,最后求和得到石子总数。

第二种方式是先对数组进行排序,然后每次取最大值除二再重新插入数组,不过这样的时间复杂度是O(NlogN) + O(kN)【插入的复杂度】

这样的时间复杂度反而远超过第一种方式。

力扣官方题解给出了另一种思路

int minStoneSum(vector<int>& piles, int k) {
        // 生成最大堆
        make_heap(piles.begin(), piles.end());
        for (int i = 0; i < k; ++i){
            // 单次操作:记录并弹出最大值,修改后重新添加进堆
            pop_heap(piles.begin(), piles.end());
            piles.back() -= piles.back() / 2;
            push_heap(piles.begin(), piles.end());
        }
        return accumulate(piles.begin(), piles.end(), 0);
    }

通过堆操作来实现每次找到最大值。