这是我参与8月更文挑战的第19天,活动详情查看:8月更文挑战
1961. 检查字符串是否为数组前缀
思路分析
这道题坑还是挺多的,最开始以为可以将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. 移除石子使总数最小
思路分析
答案要求我们返回石子的最小总数,而每次操作是将一个数/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);
}
通过堆操作来实现每次找到最大值。