终于进行到这一阶段了!
对于图问题,标准的解法是 标记数组加 dfs, 考查的抽象能力:情景问题转换为图的搜索问题。
第一个简单的问题:岛屿问题
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void dfs(vector < vector<int> >&mark ,vector < vector<int> >& ver, int x, int y ,int &M)
{
mark[x][y] = 1;
static const int dx[] = {-1 ,1 , 0 ,0};
static const int dy[] = {0 ,0 , -1 ,1};
for(int i=0; i<4 ;++i)
{
int newx = dx[i] +x;
int newy = dy[i] +y;
if( newx<0 || newx >= mark.size()|| newy <0 || newy >=mark[newx].size())
{
continue;
}
if( mark[newx][newy]==0 && ver[newx][newy] == 1)
{
dfs(mark,ver,newx,newy,M);
}
}
}
int main()
{
int M;
vector < vector<int> > ver;
cin >> M;
int num = 0;
vector < vector<int> > mark(M ,vector<int>(M,0));
//处理输入
for(int i=0; i< M;++i)
{ vector<int> tmp;
int tmpm;
for(int j=0; j<M; ++j )
{
cin >> tmpm;
tmp.push_back(tmpm);
}
ver.push_back(tmp);
tmp.clear();
}
for (int i=0 ;i<M ;++i)
for(int j=0;j<M;++j)
{
if(mark[i][j]==0 && ver[i][j]==1)
{
dfs(mark,ver,i,j,M);
cout << i <<j << endl ;
num ++;
}
}
cout << num << endl;
/*
for (int i=0;i<ver.size();++i)
for(int j=0;j<ver.size();++j)
cout << ver[i][j] << endl;*/
}
这个题最简单的搜索问题,对图遍历了一遍,标记数组没有更新。
同学的一个python的写法,总感觉不对,没加标记数组,边界条件也判断不清楚!代码的参考点在处理输入上!
class Solution:
def IslandsNums(self, grid):
if len(grid) == 0 or grid is None:
return 0
m = len(grid)
n = len(grid[0])
count = 0
for i in range(m):
for j in range(n):
if grid[i][j] == 1:
self.dfs_find(grid, i, j, m, n)
count += 1
return count
def dfs_find(self, grid, i ,j, m, n):
if grid[i][j] == 1:
grid[i][j] = 0
if (i-1 >= 0 and grid[i-1][j] == 1):
self.dfs_find(grid, i-1, j, m, n)
if (i+1 < m and grid[i+1][j] == 1):
self.dfs_find(grid, i+1, j, m, n)
if (j-1 >= 0 and grid[i][j-1]==1):
self.dfs_find(grid, i, j-1, m, n)
if (j+1 < n and grid[i][j+1]==1):
self.dfs_find(grid, i, j+1, m, n)
return
M = int(input())
matrix = []
for i in range(M):
matrix.append(list(map(int, input().split(' '))))
print(Solution().IslandsNums(matrix))
第二个问题:词语阶梯
图的表示与构造:邻接表
构造成队列的形式是方便向搜索队列中添加。
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
using namespace std;
bool conncet(const string word1,const string word2)
{
int cnt = 0;
for(int i=0 ;i<word1.length();++i)
{
if(word1[i]!= word2[i])
{
cnt ++;
}
}
return cnt == 1;
}
//构造邻接表
void construct_graph(string &beginWord, vector<string> &wordList,
map<string ,vector<string> > &graph)
{
wordList.push_back(beginWord);
for(int i=0;i<wordList.size();++i)
graph[wordList[i]] = vector<string>();
for(int i=0 ; i<wordList.size();++i)
for(int j =i+1 ;j<wordList.size() ;++j)
if(conncet(wordList[i],wordList[j]))
{
graph[wordList[i]].push_back(wordList[j]);
graph[wordList[j]].push_back(wordList[i]);
}
}
int BFS( string &beginWord,string &endWord,map<string,vector<string> >&graph)
{
queue<pair<string,int> >Q; //搜索队列<顶点,步数>
set<string> visit; //记录访问过的顶点
Q.push(make_pair(beginWord,1));//添加起始点,起始点步数为1
visit.insert(beginWord); //标记起点已经访问过
while(!Q.empty())
{
string node = Q.front().first;
int step = Q.front().second;
Q.pop();//弹出节点
if(node == endWord)
return step;
//取node的全部临时节点放入队列
const vector<string> &neighbors = graph[node];
for(int i=0;i<neighbors.size();++i)
{
if(visit.find(neighbors[i]) == visit.end())
{
Q.push(make_pair(neighbors[i],step+1));
visit.insert(neighbors[i]);
}
}
}
return 0;
}
class Solution
{
public:
int getlenth(string beginWord,string endWord,vector<string>& wordList)
{
map<string,vector<string> >graph;
construct_graph(beginWord,wordList,graph);
return BFS(beginWord,endWord,graph);
}
};
int main()
{
string beginWord ="hit" ;
string endWord = "cog" ;
vector<string> wordList;
wordList.push_back("hot");
wordList.push_back("dot");
wordList.push_back("dog") ;
wordList.push_back("lot");
wordList.push_back("log");
wordList.push_back("cog");
Solution solve;
int result = solve.getlenth(beginWord,endWord,wordList);
cout <<result;
return 0;
}
第三个问题:
扫描二维码关注公众号,回复:
6394205 查看本文章
这个问题可以转换为一个有向联通图的搜索问题:即一个节点的关注度c =其它所有节点到本节点的所有路径和
然后对N个节点都进行这样的操作!这个题目还是很有难度的。
一:处理输入,保存成有向连通图
int main()
{
int N = 0;
cin >> N;
int M = 0;
cin >> M;
vector<int>p;
for (int i = 0; i<2 * M; ++i)
{
int t = 0;
cin >> t;
p.push_back(t);
}
vector<vector<int>>r(N, vector<int>(N, 0));
for (int i = 2; i<=2 * M; i += 2)
{
r[p[i - 1] - 1][p[i - 2] - 1] = 1;
}
Solution s;
cout << s.findCircleNum(r) << endl;
//system("PAUSE");
return 0;
}
第二部:设计算法