LeetCode 575. 分糖果 / 237. 删除链表中的节点 / 407. 接雨水 II
Posted Zephyr丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 575. 分糖果 / 237. 删除链表中的节点 / 407. 接雨水 II相关的知识,希望对你有一定的参考价值。
575. 分糖果
2021.11.01 每日一题
题目描述
Alice 有 n 枚糖,其中第 i 枚糖的类型为 candyType[i] 。Alice 注意到她的体重正在增长,所以前去拜访了一位医生。
医生建议 Alice 要少摄入糖分,只吃掉她所有糖的 n / 2 即可(n 是一个偶数)。Alice 非常喜欢这些糖,她想要在遵循医生建议的情况下,尽可能吃到最多不同种类的糖。
给你一个长度为 n 的整数数组 candyType ,返回: Alice 在仅吃掉 n / 2 枚糖的情况下,可以吃到糖的最多种类数。
示例 1:
输入:candyType = [1,1,2,2,3,3]
输出:3
解释:Alice 只能吃 6 / 2 = 3 枚糖,由于只有 3 种糖,她可以每种吃一枚。
示例 2:
输入:candyType = [1,1,2,3]
输出:2
解释:Alice 只能吃 4 / 2 = 2 枚糖,不管她选择吃的种类是 [1,2]、[1,3] 还是 [2,3],她只能吃到两种不同类的糖。
示例 3:
输入:candyType = [6,6,6,6]
输出:1
解释:Alice 只能吃 4 / 2 = 2 枚糖,尽管她能吃 2 枚,但只能吃到 1 种糖。
提示:
n == candyType.length
2 <= n <= 10^4
n 是一个偶数
-10^5 <= candyType[i] <= 10^5
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/distribute-candies
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
统计种类,如果种类大于一半,那么只能分一半不同的糖,否则就是分种类数的糖
class Solution {
public int distributeCandies(int[] candyType) {
int type = 0;
int n = candyType.length;
Set<Integer> set = new HashSet<>();
for(int i = 0; i < n; i++){
set.add(candyType[i]);
}
int l = set.size();
if(l < n / 2)
return l;
else
return n / 2;
}
}
237. 删除链表中的节点
2021.11.02 每日一题
题目描述
请编写一个函数,用于 删除单链表中某个特定节点 。在设计函数时需要注意,你无法访问链表的头节点 head ,只能直接访问 要被删除的节点 。
题目数据保证需要删除的节点 不是末尾节点 。
示例 1:
输入:head = [4,5,1,9], node = 5
输出:[4,1,9]
解释:指定链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9
示例 2:
输入:head = [4,5,1,9], node = 1
输出:[4,5,9]
解释:指定链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9
示例 3:
输入:head = [1,2,3,4], node = 3
输出:[1,2,4]
示例 4:
输入:head = [0,1], node = 0
输出:[1]
示例 5:
输入:head = [-3,5,-99], node = -3
输出:[5,-99]
提示:
链表中节点的数目范围是 [2, 1000]
-1000 <= Node.val <= 1000
链表中每个节点的值都是唯一的
需要删除的节点 node 是 链表中的一个有效节点 ,且 不是末尾节点
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/delete-node-in-a-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
删除单向链表的结点,就是使前一个结点的指针改变指向,但是发现这里没有给前一个结点,那么怎么删除呢
只能是通过复制,将后一个结点的值复制到当前结点,然后使当前结点的指针指向后一个结点的后一个结点
相当于删除了下一个结点
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public void deleteNode(ListNode node) {
//给我整不会了
//只能复制了?
node.val = node.next.val;
node.next = node.next.next;
}
}
407. 接雨水 II
2021.11.03 每日一题
题目描述
给你一个 m x n 的矩阵,其中的值均为非负整数,代表二维高度图每个单元的高度,请计算图中形状最多能接多少体积的雨水。
示例 1:
输入: heightMap = [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]]
输出: 4
解释: 下雨后,雨水将会被上图蓝色的方块中。总的接雨水量为1+2+1=4。
示例 2:
输入: heightMap = [[3,3,3,3,3],[3,2,2,2,3],[3,2,1,2,3],[3,2,2,2,3],[3,3,3,3,3]]
输出: 10
提示:
m == heightMap.length
n == heightMap[i].length
1 <= m, n <= 200
0 <= heightMap[i][j] <= 2 * 10^4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/trapping-rain-water-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
这个确实难了
先回顾一下经典问题,接雨水,也就是二维的情况,有好几种解法
看一个位置能存储多少水就是看这个位置左右两端的最高高度,所以统计一个位置左右两端的最高高度,较小值减去当前位置高度就是能存储的水量
或者用单调栈,单调递减,栈中存储下标,如果比栈顶大了,那么就说明栈顶能存水了,就计算栈顶的存水量
或者还可以按行求
那么换成三维的应该怎么做呢
依然是相同的思路,一个位置可以存水量,也是看它的周围,但是和二维不同的是,如果上下左右有比它高的,但是也有比它低的,水有可能会流出去,所以需要维护的是一个圈
所以这里先确定四周,四个边界是不可能存水的,所以高度是确定的
然后再找到边界上高度最低的点,那么依据木桶原理,这个位置周围的存水量可以计算,具体配图看官解,很清晰
class Solution {
public int trapRainWater(int[][] heightMap) {
//咋做呢,半年前还做过
//依据二维的做法,看每个位置前后左右的高度吗
//首先看四个边界的格子,它们是不可能存水的,所以将他们的信息(x,y,h)放入优先队列中
//这就相当于给中间的所有格子框定了一个范围,存储的水量是不可能超过这个范围的
//然后开始弹出队列顶端的元素,即高度最小的值
//然后去遍历这个位置的四周,如果有比它还小的高度,那么说明这个高度可以存水,并且将存水后的高度放入队列中
//如果没有比它小的高度,也放入队列中
//当所有位置都遍历完,就可以得到答案
int m = heightMap.length;
int n = heightMap[0].length;
int[][] dir = {{0,1}, {0,-1}, {1,0}, {-1,0}};
PriorityQueue<int[]> pq = new PriorityQueue<>((a,b) ->(a[2] - b[2]));
boolean[][] used = new boolean[m][n];
//放周围元素
for(int i = 0; i < m; i++){
pq.offer(new int[]{i, 0, heightMap[i][0]});
pq.offer(new int[]{i, n - 1, heightMap[i][n - 1]});
used[i][0] = true;
used[i][n - 1] = true;
}
for(int i = 1; i < n - 1; i++){
pq.offer(new int[]{0, i, heightMap[0][i]});
pq.offer(new int[]{m - 1, i, heightMap[m - 1][i]});
used[0][i] = true;
used[m - 1][i] = true;
}
int res = 0;
//然后处理优先队列
while(!pq.isEmpty()){
int[] top = pq.poll();
int x = top[0];
int y = top[1];
int h = top[2];
for(int i = 0; i < 4; i++){
int nx = x + dir[i][0];
int ny = y + dir[i][1];
if(nx >= 0 && nx < m && ny >= 0 && ny < n && !used[nx][ny]){
used[nx][ny] = true;
if(heightMap[nx][ny] < h){
res += h - heightMap[nx][ny];
pq.offer(new int[]{nx, ny, h});
}else{
pq.offer(new int[]{nx, ny, heightMap[nx][ny]});
}
}
}
}
return res;
}
}
以上是关于LeetCode 575. 分糖果 / 237. 删除链表中的节点 / 407. 接雨水 II的主要内容,如果未能解决你的问题,请参考以下文章