前几天熬夜写的一部分代码,可以用于计算所有连通区域周长。题目:二维数组用0/1表示,计算所有连通区域最大的连通区域周长。
思路:计算所有联通区域周长,放进不同的数组求最大的长度。(不完善,最终结果有问题)
#include <iostream>
#include <cstring>
#include <utility>
#include<vector>
#include<algorithm>
using namespace std;
class Solution {
public :
//计算所有连通区域的周长
int islandPerimeter(vector<vector<int>>& grid) {
int res = 0;
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[0].size(); j++) {
if (grid[i][j] == 1) {
if (i == 0 || grid[i - 1][j] == 0) res++;
if (i == grid.size() - 1 || grid[i + 1][j] == 0) res++;
if (j == 0 || grid[i][j - 1] == 0) res++;
if (j == grid[0].size()- 1 || grid[i][j + 1] == 0) res++;
}
}
}
return res;
}
//区分所有range,小的range置为0
//遍历,如果下面和右边都为0或者空,则创建新的vector
vector<vector<pair<int,int>>> cutrange(vector<vector<int>>& grid){
//遍历,判断是否为1,下和右是否为0,为0,则属于一个区域
int res = 0;
vector<vector<int>> v_cut;
vector<int> v_son;
vector<vector<pair<int,int>>> v_cutij;//记录下标
vector<pair<int,int>> son_ij;
pair<int,int>p_ij;
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[0].size(); j++) {
if (grid[i][j] == 1)
{
v_son.push_back(grid[i][j]);
p_ij.first=i;p_ij.second=j;
son_ij.push_back(p_ij);
if((j == grid[0].size()- 1 ||grid[i][j + 1] ==0)&&(i== grid.size() - 1 || grid[i + 1][j]==0)){
v_cut.push_back(v_son);
v_son.clear();
v_cutij.push_back(son_ij);
son_ij.clear();
}
}
}
}
return v_cutij;
}
vector<vector<int>> xyis1(vector<vector<int>>& grid,vector<vector<pair<int,int>>>& v_p_xy,int pos){
vector<pair<int,int>> vp;
for (int i=0; i<v_p_xy[0].size(); i++){
vp.push_back(v_p_xy[pos][i]);
}
vector<int>xy(grid[0].size(),0);
vector<vector<int>> v_xy(grid.size(),xy);
for(vector<pair<int,int>>::const_iterator v_it=vp.begin();v_it!=vp.end();v_it++)
{
v_xy[v_it->first][v_it->second]=1;
}
return v_xy;
}
void print(vector<vector<int>>&v){
for(vector<vector<int>>::const_iterator it=v.begin();it!=v.end();it++){
for(vector<int>::const_iterator v_it=(*it).begin();v_it!=(*it).end();v_it++){
cout<<*v_it<<" ";
}
cout<<endl;
}
}
};
int main(){
//输入和初始化
Solution ss;
vector<vector<int>>v;
int n=0;
cin>>n;
for(int i=0;i<n;i++)
{
vector<int>land;
for(int j=0;j<n;j++)
{
int in;
cin>>in;
land.push_back(in);
}
v.push_back(land);
}
//切分所有连通区域,返回每个连通区域的索引对
vector<vector<pair<int,int>>> v_cutij=ss.cutrange(v);
//ss.print(v_cut);//测试代码
//最大联通区域id
int max=0;
vector<int>son_maxsize;
vector<pair<int,int>>::iterator v_p_max;
for(vector<vector<pair<int,int>>>::iterator it=v_cutij.begin();it!=v_cutij.end();it++)
{
son_maxsize.push_back((*it).size());
if((*it).size()>max){
max=(*it).size();
}
}
int pos=find(son_maxsize.begin(),son_maxsize.end(),max)-son_maxsize.begin();
//for_each(son_maxsize.begin(),son_maxsize.end(),print);//测试代码
//cout<<endl;
//创建新的grid只包含最大range
vector<vector<int>> vtarget;
vtarget=ss.xyis1(v,v_cutij, pos);
ss.print(vtarget);//测试代码
//计算周长
cout<<ss.islandPerimeter(vtarget)<<endl;
return 0;
}
只计算所有连通区域周长的代码如下:
注意!!!
1、要用v[i][j]表示vector二维数组,一定需要初始化二维数组;
2、访问二维数组一定要处理越界!!!
class Solution {
public :
//计算所有连通区域的周长
int islandPerimeter(vector<vector<int>>& grid) {
int res = 0;
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[0].size(); j++) {
if (grid[i][j] == 1) {
if (i == 0 || grid[i - 1][j] == 0) res++;
if (i == grid.size() - 1 || grid[i + 1][j] == 0) res++;
if (j == 0 || grid[i][j - 1] == 0) res++;
if (j == grid[0].size()- 1 || grid[i][j + 1] == 0) res++;
}
}
}
return res;
}
};
int main(){
Solution ss;
int m=4,n=6;
vector<int> v1(m,0);
vector<vector<int>>v(n,v1);
//设置1个数
v[0][0] = 1; v[0][5] = 1;
v[2][1] = 1; v[2][5] = 1;
//计算周长
cout<<ss.islandPerimeter(v)<<endl;
return 0;
}
在大厂面试题里面,,这种二维数组的题目非常多,处理二维数组也要小心。因为机试的时候代码很难找出错误,尤其是初始化和越界这种错误,编译不会有错,只有运行错误,太难了!!!!
只有慢慢总结经验才能怒斩offer 哈哈哈哈哈哈~~