leetcode第70场双周赛
第一题[2144. 打折购买糖果的最小开销]
贪心:
- 要使得花费的钱最少,就要尽可能的免费拿到价格高的糖果
class Solution {
public int minimumCost(int[] cost) {
//这感觉是贪心算法
if (cost.length == 2){
return cost[0] + cost[1];
}
Arrays.sort(cost);
int res = 0;
int count = 0;
for (int i = cost.length - 1;i >= 0;i--){
if (count == 2) {
count = 0;
continue;
}
count++;
res += cost[i];
}
return res;
}
}
第二题[2145. 统计隐藏数组数目]
前缀和 + 差分数组:
需要注意的一点是结果用int会爆
前缀和数组接触的不多,刷完dp之后,会是理解的对象,以前理解的都快要忘光了。
class Solution {
public int numberOfArrays(int[] differences, int lower, int upper) {
//试着理解差分数组的范围
long sum = 0,min = 0,max = 0;
for(int i = 0;i < differences.length;i++){
sum += differences[i];
if(sum > max){
max = sum;
}else if ( sum < min){
min = sum;
}
}
int res =(int) (upper - lower + 1 -(max - min));
return res > 0? res : 0;
}
}
第三题[2146. 价格范围内最高排名的 K 样物品]
BFS + 优先队列
还是不熟练,思路想到了,但是代码不熟练,中间花了很多很多时间。中间搜索,向周围扩开,用deque做容器装二维数组中所有的数据,根据条件进行筛选放在优先队列里面进行排序,排序的规则就是题目说的,先数字小的,行小的,后列小的。
class Solution {
List<List<Integer>> res;
int[][] direct = new int[][]{{-1,0},{1,0},{0,-1},{0,1}};
public List<List<Integer>> highestRankedKItems(int[][] grid, int[] pricing, int[] start, int k) {
//想明白了,感觉还是挺简单的,比较难的点可能就在优先队列的排序规则
//试着广度优先搜索,尽可能的写一写吧
res = new LinkedList<>();
int len = grid.length;
int line = grid[0].length;
//辅助的队列
Deque<int[]> d = new ArrayDeque<>();
d.addLast(start);
PriorityQueue<int[]> queue = new PriorityQueue<>((a,b)->{
if(grid[a[0]][a[1]] == grid[b[0]][b[1]]){
if(a[0] == b[0]){
return a[1] - b[1];
}
return a[0] - b[0];
}
return grid[a[0]][a[1]] - grid[b[0]][b[1]];
});
boolean[][] visit = new boolean [len][line];
visit[start[0]][start[1]] = true;
while(!d.isEmpty() && res.size() < k){
int size = d.size();
for(int i = 0;i < size;i++){
int[] xy = d.poll();
int cprice = grid[xy[0]][xy[1]];
if(cprice == 0){
continue;
}
if(cprice == 1 || cprice < pricing[0] || cprice > pricing[1]){
}else{
queue.add(xy);
}
// 深搜还是跑不了啊
for(int j = 0;j < direct.length;j++){
int x = xy[0] + direct[j][0];
int y = xy[1] + direct[j][1];
if(x >= 0 && x < len && y >= 0 && y < line && !visit[x][y]){
d.addLast(new int[]{x,y});
visit[x][y] = true;
}
}
}
while(!queue.isEmpty() && res.size() < k){
int[] poll = queue.poll();
LinkedList<Integer> temp = new LinkedList<Integer>();
temp.add(poll[0]);
temp.add(poll[1]);
res.add(temp);
}
}
return res;
}
}
第四题 分隔长廊的方案数
排列组合:
- 每次用两个盆栽进行分组,统计两组之间盆栽的数量,相乘极为结果,为什么要mod上一个10000007呢? 我不李姐。
class Solution {
public int numberOfWays(String corridor) {
//我好像明白了,把每两个椅子之间进行分组,统计中间植物的数量,然后×在一起
int slen = 0;
int plen = 0;
long res = 1;
int mod = 1000000007;
for(int i = 0;i < corridor.length();i++){
if(corridor.charAt(i) == 'S'){
if(slen != 0 && slen % 2 == 0){
if(plen != 0){
res *= (plen + 1);
res = res % mod;
plen = 0;
}
}
slen++;
}else if(slen % 2 == 0 && slen != 0){
plen++;
}
}
if(slen == 2){
return 1;
}else if (slen % 2 != 0 || slen == 0){
return 0;
}else{
return (int)res % mod;
}
}
}