LeetCode_Nov_1st_Week
Posted 清水寺扫地僧
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode_Nov_1st_Week相关的知识,希望对你有一定的参考价值。
November 1st:575. 分糖果
November 2nd:237. 删除链表中的节点
November 3rd: 407. 接雨水 II
November 1st : 575. 分糖果
偶数长度数组表示糖果的个数,要求弟弟妹妹均分后,妹妹所得糖果的最大种类数是多少。
贪心思想,对于妹妹而言,每种糖果都先取一个,已经取过的种类的糖果都给弟弟:
- 如果糖果种类数大于等于数组长度的一半,则所获最大种类数即为数组长度的一半;
- 如果糖果种类数小于数组长度的一半,则所获最大种类数即为糖果的种类数;
//version 1
class Solution {
public:
int distributeCandies(vector<int>& candyType) {
unordered_set<int> types;
for(auto candy : candyType)
if(types.find(candy) == types.end())
types.insert(candy);
return min(types.size(), candyType.size()/2);
}
};
//version 2
class Solution {
public:
int distributeCandier(vector<int>& candyType) {
return min(unordered_set<int>(candyType.begin(), candyType.end()).size(),
candyType.size()/2);
}
};
November 2nd : 237. 删除链表中的节点
给定要删除的节点的指针作为函数参数,则我们无法得到要删除节点的pre节点。
作为替代,则将要删除节点的值赋给要删除的节点node->val = node->next->val
,再将要删除节点的next指向要删除节点的next的next节点node->next = node->next->next
即可。
评论:脑筋急转弯,没啥意思。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void deleteNode(ListNode* node) {
node->val = node->next->val;
node->next = node->next->next;
}
};
November 3rd : 407. 接雨水 II
使用图的广度优先遍历来解决,想一下木桶效应,对于一个被周围四个格子包围的格子而言,其储水的多少应当是:
around_height_min = min(height_up, height_down, height_left, height_right);
height_cur > around_height_min ? height_cur - around_height_min : 0;
所以需要用到周边格子的最小高度,那么将广度优先遍历所使用的队列替换为优先队列,也即最小堆即可。
对地图进行遍历时,每次取出已遍历过的格子中最矮的那个,将其四周的格子的储水量进行计算,累加,并更新遍历集。重复这个操作,直至遍历完整个地图,即可得到题解。
class Solution {
public:
int trapRainWater(vector<vector<int>>& heightMap) {
int m = heightMap.size(), n = heightMap[0].size();
if(m <= 2 || n <= 2) return 0; //若是地图长宽不均大于2,则无法接到雨水
//创建最小堆,也即是每次从堆中取出的格子,都是堆中最矮的
priority_queue<pair<int,int>, vector<pair<int, int>>, greater<pair<int, int>>> heap;
//记录是否已经处理过
vector<vector<bool>> visited(m, vector<bool>(n, false));
//由于边界的格子不可能储水,所以将处于边界的格子加入到堆中去,并标记处理过
for(int i = 0; i < m; ++i) {
for(int j = 0; j < n; ++j) {
if(i == 0 || i == m-1 || j == 0 || j == n-1) {
heap.push({heightMap[i][j], i*n+j});
visited[i][j] = true;
}
}
}
int ret = 0;
//四个方向数组,具体方向见下
vector<int> direct = {0, 1, 0, -1, 0}; //up right down left
//只要堆不空,说明格子没有完全处理完,则继续取出进行处理
while(!heap.empty()) {
int curHeight = heap.top().first; //所取出格子的高度
int curX = heap.top().second / n, curY = heap.top().second % n; //所取出格子的坐标
heap.pop();
for(int k = 0; k < 4; ++k) { //沿着四个方向取出在地图中且未处理的格子
int solX = curX + direct[k], solY = curY + direct[k+1];
if(solX > 0 && solX < m && solY > 0 && solY < n && !visited[solX][solY]) {
if(heightMap[solX][solY] < curHeight) { //如果旁边的格子高度小于所取格子高度,则可储水
ret += curHeight - heightMap[solX][solY]; //也即是进行广度优先图遍历
}
visited[solX][solY] = true; //再进行标记
heap.push({max(heightMap[solX][solY], curHeight), solX*n+solY}); //将旁边格子加入到最小堆
//max(heightMap[solX][solY], curHeight)对于[solX][solY]的旁边格子,储水高度是依照旁边格子的
//若是所取格子高度小于[solX][solY]格子,则加入堆时,应当是heightMap[solX][solY]
}
}
}
return ret;
}
};
以上是关于LeetCode_Nov_1st_Week的主要内容,如果未能解决你的问题,请参考以下文章