1. 利用字母组成图形
利用字母可以组成一些美丽的图形,下面给出了一个例子:
1. ABCDEFG 2. BABCDEF 3. CBABCDE 4. DCBABCD 5. EDCBABC
这是一个5行7列的图形,请找出这个图形的规律,并输出一个n行m列的图形。
输入一行,包含两个整数n和m,分别表示你要输出的图形的行数的列数。
代码:
#include <stdio.h> #include <math.h> int main() { int m, n; scanf("%d%d", &n, &m); int i, j; for (i = 0; i < n; i++) { for (j = 0; j < m; j++) { printf("%c", 65 + abs(i - j)); } printf("\n"); } return 0; }
输入输出:
5
7
ABCDEFG
BABCDEF
CBABCDE
DCBABCD
EDCBABC
--------------------------------
Process exited after 3.645 seconds with return value 0
请按任意键继续. . .
2. 子集 II
给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。
示例 1:
输入:nums = [1,2,2]
输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]
示例 2:
输入:nums = [0]
输出:[[],[0]]
提示:
1 <= nums.length <= 10
-10 <= nums[i] <= 10
代码:
#include <bits/stdc++.h> using namespace std; class Solution { public: vector<vector<int>> subsetsWithDup(vector<int> &nums) { vector<vector<int>> res; sort(nums.begin(), nums.end()); dfs(nums, 0, res); return res; } private: vector<int> stack; void dfs(vector<int> &nums, int start, vector<vector<int>> &res) { res.push_back(stack); int last = INT_MIN; for (int i = start; i < nums.size(); i++) { if (last != nums[i]) { stack.push_back(nums[i]); dfs(nums, i+1, res); stack.pop_back(); } last = nums[i]; } } };
3. 二叉树路径总和 II
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
示例 1:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]
示例 2:
输入:root = [1,2,3], targetSum = 5
输出:[]
示例 3:
输入:root = [1,2], targetSum = 0
输出:[]
提示:
树中节点总数在范围 [0, 5000] 内
-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000
代码:
#include <bits/stdc++.h> using namespace std; struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; class Solution { public: vector<vector<int>> pathSum(TreeNode *root, int sum) { vector<vector<int>> res; vector<int> track; backTrack(root, res, track, sum); return res; } void backTrack(TreeNode *root, vector<vector<int>> &res, vector<int> track, int sum) { if (!root) { return; } if (!root->left && !root->right) { sum -= root->val; track.push_back(root->val); if (sum == 0) { res.push_back(track); } track.pop_back(); sum += root->val; return; } sum -= root->val; track.push_back(root->val); backTrack(root->left, res, track, sum); backTrack(root->right, res, track, sum); track.pop_back(); sum += root->val; } };
代码2:DFS
class Solution { public: int ans = INT_MIN; int maxPathSum(TreeNode* root) { dfs(root); return ans; } int dfs(TreeNode *root){ if(!root) return 0; int left = dfs(root->left); int right = dfs(root->right); ans = max(ans,left+root->val + right); return max(0,root->val+max(left,right)); } };
附录
深度优先搜索算法
Depth-First-Search,DFS
是一种用于遍历或搜索树或图的算法。这个算法会尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。
广度优先搜索算法
Breadth-First Search,BFS
又译作宽度优先搜索,或横向优先搜索,是一种图形搜索算法。简单的说,BFS是从根节点开始,沿着树的宽度遍历树的节点。如果所有节点均被访问,则算法中止。
BFS 和 DFS 的区别
1 数据结构
bfs 遍历节点是先进先出,一般使用队列作为辅助数据结构
dfs遍历节点是先进后出,一般使用栈作为辅助数据结构
2 访问节点的方式
bfs是按层次访问的,先访问源点,再访问它的所有相邻节点,并且标记结点已访问,根据每个邻居结点的访问顺序,依次访问它们的邻居结点,并且标记节点已访问,重复这个过程,一直访问到目标节点或无未访问的节点为止。
dfs 是按照一个路径一直访问到底,当前节点没有未访问的邻居节点时,然后回溯到上一个节点,不断的尝试,直到访问到目标节点或所有节点都已访问。
3 应用
bfs 适用于求源点与目标节点距离近的情况,例如:求最短路径。
dfs 更适合于求解一个任意符合方案中的一个或者遍历所有情况,例如:全排列、拓扑排序、求到达某一点的任意一条路径。

