一.深度优先搜索(DFS)
一般深度优先搜索设计递归算法的步骤如下:
1.先按照一般递归算法的思路写递归结束条件
2.主体部分写满足题目条件则进入递归
3.回溯,需要先记录进入递归前的某些参数
以一个题目说明:
给定一个整型数组, 你的任务是找到所有该数组的递增子序列并输出其数量,递增子序列的长度至少是2。
示例:
输入: [4, 6, 7, 7]
输出: 8
解释:递增子序列包括:[[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]],共8个
说明:
给定数组的长度不会超过15。
数组中的整数范围是 [-100,100]。
给定数组中可能包含重复数字,相等的数字应该被视为递增的一种情况。
#include<iostream>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;
class Solution{
public:
bool is_overlap(const vector<int> &num, int last, int index) {
for(int i = last+1; i < index; i++) {
if(num[i] == num[index]) {
return false;
}
}
return true;
}
void dfs(const vector<int> &nums, int last, int index, vector<int> &s, vector<vector<int>> &res) {
if(nums.size() == index) return;//递归结束条件
if((s.empty() || nums[index] >= s.back()) && is_overlap(nums, last, index)) {
s.push_back(nums[index]);
if(s.size() >= 2) {
res.push_back(s);
}
dfs(nums, index, index+1, s, res);//满足某些条件则进入递归
s.pop_back();//回溯
}
dfs(nums, last, index+1, s, res);
}
vector<vector<int>> increaseOrder(vector<int>& nums) {
vector<vector<int>> res;
vector<int> s;
dfs(nums, -1, 0, s, res);
return res;
}
};
int main(){
vector<int> nums;
int n,data;
cin>>n;
for(int i=0;i<n;i++){
cin>>data;
nums.push_back(data);
}
vector<vector<int>> res=Solution().increaseOrder(nums);
cout<<res.size()<<endl;
return 0;
}
二.宽度优先搜索(BFS)
按照宽度优先搜索的思想,一般算法的设计是利用辅助队列从初始点不断的进行扩展,这个过程类似二叉树的层次遍历。
示例题如下:
给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。
两个相邻元素间的距离为 1 。
示例 1:
输入:
0 0 0
0 1 0
0 0 0
输出:
0 0 0
0 1 0
0 0 0
注意:
给定矩阵的元素个数不超过 10000。
给定矩阵中至少有一个元素是 0。
矩阵中的元素只在四个方向上相邻: 上、下、左、右。
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
class Solution{
public:
vector<vector<int>> updateMatrix(vector<vector<int> >& matrix){
int m=matrix.size();
int n=matrix[0].size();
if(m==0||n==0) return {};
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};//方向数组,也是经常这样设计
queue<pair<int,int>> q;
vector<vector<int>> flag(m,vector<int>(n,1));//标识是否遍历过
vector<vector<int>> res(m,vector<int>(n,0));
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(matrix[i][j]==0){
q.push(make_pair(i,j));//将一些初始点加入辅助队列
flag[i][j]=0;
}
}
}
while(!q.empty()){
int cnt=q.size();
while(cnt--){
pair<int,int> temp=q.front();
q.pop();
int row=temp.first;
int col=temp.second;
for(int i=0;i<4;i++){//四个方向进行扩展
int x=dx[i]+row;
int y=dy[i]+col;
if(x>=0 && x<m && y>=0 && y<n &&flag[x][y]==1){//新点要满足基本条件
res[x][y]=res[row][col]+1;
q.push(make_pair(x,y));//加入辅助队列进行下一轮扩展
flag[x][y]=0;
}
}
}
}
return res;
}
};
int main()
{
vector<vector<int> > matrix;
int m,n;
cin>>m;
cin>>n;
char ch;
for(int i=0; i<m; i++)
{
vector<int> aLine;
for(int j=0; j<n; j++)
{
cin>>ch;
aLine.push_back(ch-'0');
}
matrix.push_back(aLine);
}
vector<vector<int>> res=Solution().updateMatrix(matrix);
for(int i=0; i<res.size(); i++)
{
vector<int> aLine = res[i];
for(int j=0; j<aLine.size(); j++)
cout<<aLine[j];
cout<<endl;
}
return 0;
}