1.二叉树的锯齿形层序遍历
原题链接
总代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
vector<vector<int>>v;
vector<int>v1;
queue<TreeNode*>que;que.push(root);//BFD的预备:创造队列及添头元素
int a=0;
if(!root)return v;
while(que.size())
{
int b=que.size();//先记录下一层的元素数 以防之后que.size()值改变
for(int i=0;i<b;i++)//for的存在可以一层访问完之后进行下一层的预备操作
{
root=que.front();que.pop();
v1.push_back(root->val);//中间条件依据题意而变
if(root->left)que.push(root->left);//两个if的存在 使队列中不存在空指针的情况
if(root->right)que.push(root->right);
}
if(a==1)reverse(v1.begin(),v1.end());//容器中元素的反转
v.push_back(v1);v1.clear();
if(a==0)a=1;
else a=0;
}
return v;
}
};
代码分析
因为que.size()的值会运行for里面代码时变值
而第一段代码是直接赋值到b
但第二段代码是直接赋值到i,相对于第一段,代码更优化了
//不完美代码
int b=que.size();
for(int i=0;i<b;i++)
{
.........
}
//完美代码
for(int i=que.size();i>0;i--)
{
.........
}
2.Catch That Cow(判重or剪枝)
原题链接
总代码
#include<iostream>
#include<map>
#include<queue>
using namespace std;
struct node
{
node() {};
node(int nn, int tt) { n = nn; t = tt; }//很巧妙 不用再设置 直接匿名创建即可
int n;//当前所在点
int t;//记录层数 即题中要移动的次数
};
int main()
{
int n1,k; cin >> n1 >> k;
queue<node>que;
que.push(node(n1, 0));
map<int, bool>ma;//用于去重
while (que.size())
{
node now = que.front(); que.pop();
if (now.n == k)
{
cout << now.t << endl;
break;
}
//一般来说此if是对于即将加入队列的元素进行判断的
//而我是对当前进行判断 算是用时间换取空间了
if (!ma[now.n])
{
ma[now.n] = true;
if (now.n > k)//剪枝
{
que.push(node(now.n - 1, now.t+1));//"++now.t"不能改成写
}
else
{
que.push(node(now.n - 1, now.t+1));
que.push(node(now.n + 1, now.t+1));
que.push(node(2 * now.n, now.t+1));
}
}
}
}
3.The Wedding Juicer(洪水填充+优先队列)
原题链接
感悟
1.优先队列
以数组的角度横向看 pq.top()对应的元素是最右边的 而不是最左边 与queue.front()不同
优先队列通常用堆
堆是一种特殊的树形数据结构,每个节点都有一个值,通常我们所说的堆都是二叉堆。
总代码
代码一:自己的思路
#include<iostream>
#include<queue>
using namespace std;
int vis[301][301];
int fan[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };
struct node
{
int x, y;
int vale;
}a[90009];
//仿函数
class judge
{
public:
bool operator()(node a, node b)
{
return a.vale > b.vale;
}
};
int main()
{
//自定义类型时 要写入三个参数
priority_queue<node,vector<node>,judge>pq;//此队列里面始终为边界
//使sort()所导致的时间复杂度大于优先队列的时间复杂度
int w, h;
cin >> w >> h;
int q = 1; int ans = 0;
for (int i = 1; i <= h; i++)
{
for (int j = 1 ;j <= w; j++)
{
cin >> a[q].vale;
a[q].x = j; a[q].y = i;
if (i == h || j == w || i == 1 || j == 1)
{
pq.push(a[q]);
vis[i][j] = 1;
}
q++;
}
}
while (pq.size())
{
node b = pq.top(); pq.pop();
cout << b.vale << endl;
for (int i = 0; i < 4; i++)
{
//锁定位置
int xx = b.x + fan[i][0];
int yy = b.y + fan[i][1];
if (xx > w || yy > h || xx <= 0 || yy <= 0)continue;
if (vis[yy][xx] == 0)
{
if (a[(yy-1) * w + xx].vale >= b.vale)
{
pq.push(a[(yy-1) * w + xx]);
}
else
{
ans += b.vale - a[(yy-1) * w + xx].vale;
a[(yy - 1) * w + xx].vale = b.vale;
pq.push(a[(yy - 1) * w + xx]);
}
vis[yy][xx] = 1;
}
}
}
cout << ans << endl;
}
代码二:GPT的思路
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
struct Node {
int x, y, height;
bool operator>(const Node& other) const {
return height > other.height; // for min-heap
}
};
int main() {
int W, H;
cin >> W >> H;
vector<vector<int>> heights(H, vector<int>(W));
vector<vector<bool>> visited(H, vector<bool>(W, false));
priority_queue<Node, vector<Node>, greater<Node>> pq;
// Read heights
for (int i = 0; i < H; ++i)
for (int j = 0; j < W; ++j)
cin >> heights[i][j];
// Push all edge blocks into the priority queue
for (int i = 0; i < H; ++i) {
pq.push({ i, 0, heights[i][0] });
pq.push({ i, W - 1, heights[i][W - 1] });
visited[i][0] = visited[i][W - 1] = true;
}
for (int j = 0; j < W; ++j) {
pq.push({ 0, j, heights[0][j] });
pq.push({ H - 1, j, heights[H - 1][j] });
visited[0][j] = visited[H - 1][j] = true;
}
// Directions for neighbors (up, down, left, right)
int directions[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
long long totalVolume = 0;
while (!pq.empty()) {
Node current = pq.top();
pq.pop();
for (auto& dir : directions) {
int nx = current.x + dir[0];
int ny = current.y + dir[1];
if (nx >= 0 && nx < H && ny >= 0 && ny < W && !visited[nx][ny]) {
visited[nx][ny] = true;
// Determine if it can hold juice
if (heights[nx][ny] < current.height) {
totalVolume += current.height - heights[nx][ny];
pq.push({ nx, ny, current.height }); // update height to current height
}
else {
pq.push({ nx, ny, heights[nx][ny] });
}
}
}
}
cout << totalVolume << endl;
return 0;
}
差别
总体思路一样 但二维高度的存在形式不一样