LeetCode题目总结——图

LeetCode题目总结——回溯

1. 最短路径

BFS

当边的权重为0、1时,采用BFS即可获取起点与终点之间的最短路径。
当终点唯一且已知时,可采用双向BFS进行加速。

  1. 0126 - 单词接龙 II
    注意在计算单词节点之间的连接关系时,可采用hash表加速运算。
map<string, vector<int>> hash;
for (int i = 0; i < N; ++i) {
	for (int k = 0; k < M; ++k) {
		string key = wordList[i];
		key[k] = '*';
		if (hash.find(key) == hash.end()) 
			hash[key] = { i };
		else 
			hash[key].emplace_back(i);
	}
}
vector<set<int>> edges(N);
for (int i = 0; i < N; ++i) {
	for (int k = 0; k < M; ++k) {
		string key = wordList[i];
		key[k] = '*';
		for (int j : hash[key]) {
			edges[i].insert(j);
		}
	}
}

Dijkstra算法

当边的权重不为0、1时,BFS维护的队列改用优先级队列。

// 定义队列元素
struct Item {
	int idx;
	int dist;
	bool operator<(const Item& that) const {
		dist > that.dist; // 小堆顶
		dist < that.dist; // 大堆顶
	}
}// 定义seen数组
vector<bool> seen(N);
fill(seen.begin(), seen.end(), false);

// 定义优先级队列
priority_queue<Item> q;
q.emplace(0, 0);

// 搜索
while (!q.empty()) {
	// 获取堆顶元素
	auto item = q.top();
	q.pop();
	
	// 验证seen数组
	if (seen[item.idx]) continue;
	seen[item.idx] = true;

	// 添加相邻元素至队列,并更新距离数组
	for (auto neighbor : neighbors) {
		if (seen[neighbor.idx]) continue;
		q.emplace(neighbor.idx, op(item.dist, dist(neighbor, item)));
	}
}

2. 并查集

class UnionFind {
	int n;
	vector<int> parent, size;

public:
	UnionFind(int n) {
		this->n = n;
		parent = vector<int>(n);
		size = vector<int>(n, 1);
    	for (int i = 0; i < n; ++i)
      		parent[i] = i;
  	}

  	int find(int idx) {
  		int p = parent[idx];
    	if (p != idx) {
      		parent[idx] = find(p);
      	}
    	return parent[idx];
  	}

  	void connect(int a, int b) {
    	int pa = find(a), pb = find(b);
    	if (pa != pb) {
      		if (size[pa] > size[pb]) {
        		parent[pb] = pa;
        		size[pa] += size[pb];
      		} else {
        		parent[pa] = pb;
        		size[pb] += size[pa];
      		}
    	}
    }

	void check(int a, int b) {
		return find(a) == find(b);
	}
  1. 周赛220-5632 - 检查边长度限制的路径是否存在
    注意为离线判定,因此,可根据判定阈值将判定条件排序,然后从小判定阈值开始,每次只将小于判定阈值的边加入图中,这样可以保证加入图中的边全部满足判定需求,只需判定当前图中的两节点是否联通即可。
    判断两节点是否联通,可使用并查集。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值