广度优先搜索(BFS)

1.二叉树的锯齿形层序遍历

原题链接

. - 力扣(LeetCode)

总代码

/**
 * 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剪枝)

原题链接

3278 -- Catch That Cow

总代码

#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(洪水填充+优先队列)

原题链接

2227 -- 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;
}

差别

总体思路一样  但二维高度的存在形式不一样

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值