P161
6.设计一个算法求出根节点到叶子结点的所有路径
// By SnowDream
#include <bits/stdc++.h>
using namespace std;
// 定义二叉树节点
typedef struct node {
int data; // 数据元素
struct node *lchild; // 指向左孩子结点
struct node *rchild; // 指向右孩子结点
} Node;
// 递归查找路径
void findPathsHelper(Node* node, const string& path, vector<string>& paths) {
if (node != nullptr) {
// 将当前节点添加到路径中
stringstream ss;
ss << node->data;
string strVal = ss.str();
if (node->lchild == nullptr && node->rchild == nullptr) { // 如果到达叶子节点
paths.push_back(path + strVal); // 记录完整路径
} else {
// 如果不是叶子节点,则继续向下搜索
findPathsHelper(node->lchild, path + strVal + "->", paths);
findPathsHelper(node->rchild, path + strVal + "->", paths);
}
}
}
// 返回从根到叶子的所有路径
vector<string> findPaths(Node* root) {
vector<string> paths;
if (root != nullptr) {
findPathsHelper(root, "", paths);
}
return paths;
}
// 构建二叉树
Node* buildTree(vector<string>& nodes) {
if (nodes.empty() || nodes[0] == "#")
return nullptr;
Node* root = new Node{stoi(nodes[0]), nullptr, nullptr};
queue<Node*> q;
q.push(root);
int i = 1;
while (!q.empty() && i < nodes.size()) {
Node* current = q.front();
q.pop();
if (nodes[i] != "#") {
current->lchild = new Node{stoi(nodes[i]), nullptr, nullptr};
q.push(current->lchild);
}
i++;
if (i < nodes.size() && nodes[i] != "#") {
current->rchild = new Node{stoi(nodes[i]), nullptr, nullptr};
q.push(current->rchild);
}
i++;
}
return root;
}
void DestroyTree(Node* node) {
if (node != nullptr) {
DestroyTree(node->lchild);
DestroyTree(node->rchild);
delete node;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
vector<string> input = {"1", "2", "3", "#", "5"};
Node* root = buildTree(input);
vector<string> paths = findPaths(root);
for (const auto& path : paths) {
cout << path << endl;
}
DestroyTree(root);
return 0;
}
P162
9.给出一个 n * m的矩阵,每个点有一个权值,从矩阵左下走到右上(可以走四个方向),让你找到一条路径 使得该路径所路过的权值和最小,输出最小权值和。
// By SnowDream
#include <bits/stdc++.h>
using namespace std;
int minPathSum(vector<vector<int>>& grid) {
int n = (int)grid.size();
if (n == 0) return 0;
int m = (int)grid[0].size();
vector<vector<int>> dp(n, vector<int>(m, INT_MAX));
// 初始化起点
dp[n-1][0] = grid[n-1][0];
// 使用优先队列来实现Dijkstra算法
priority_queue<pair<int, pair<int, int>>, vector<pair<int, pair<int, int>>>, greater<>> pq;
pq.push({grid[n-1][0], {n-1, 0}});
while (!pq.empty()) {
auto current = pq.top();
pq.pop();
int dist = current.first;
int x = current.second.first;
int y = current.second.second;
// 如果已经找到了到达右上角的路径,则返回结果
if (x == 0 && y == m-1) return dist;
// 检查四个方向
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
for (int i = 0; i < 4; ++i) {
int newX = x + dx[i];
int newY = y + dy[i];
if (newX >= 0 && newX < n && newY >= 0 && newY < m) {
int newDist = dist + grid[newX][newY];
// 只有当找到更短的路径时才更新并加入队列
if (newDist < dp[newX][newY]) {
dp[newX][newY] = newDist;
pq.push({newDist, {newX, newY}});
}
}
}
}
return dp[0][m-1];
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
vector<vector<int>> grid = {{1,1,1},{1,1,1},{1,1,1}};
cout << "最小路径和: " << minPathSum(grid) << endl;
return 0;
}