传统弱校HFUT的蒟蒻,真相只有一个

算法复习:BFS与DFS

BFS

leetcode 279. 完全平方数

vector存每一层的节点,弹出一个节点就压入这个节点所有的子节点。

从上往下维护一颗树,根节点是要找的n,第一层子节点是父节点减去i*i以后的值,一直到发现0为止。

注意必须要用一个标记数组记录已经走过的点避免重复查找,否则会超时

如果更改一下顺序,按从大到小的顺序查会更快一点。

#include<vector>
#include<queue>
#include<map>
class Solution {
public:
    int numSquares(int n)
    {
        vector<int>donser;
        queue<int>tree;
        map<int,bool>lable;
        for(int i=1;i*i<=n;i++)
        {
            tree.push(n-i*i);
            donser.push_back(i*i);
        }
        int deepth=0;
        while(n)
        {
            int size=tree.size();
            deepth++;
            for(int i=0;i<size;i++)
            {
                int next=tree.front();
                tree.pop();
                if(next==0)
                    return deepth;
                for(int j=0;j<donser.size();j++)
                {
                    if(lable[next-donser[j]]==true)
                    {
                        continue;
                    }    
                    if(donser[j]<=next)
                    {
                        tree.push(next-donser[j]);
                        lable[next-donser[j]]=true;
                    }
                    else
                        break;
                }
            }
        }
        return 0;
    }
};
leetcode 279

 

 

 

DFS

leedcode 695. 岛屿的最大面积

向四个方向搜,走过的地方做标记

class Solution {
public:
    int dfs(int i,int j,vector<vector<int>>& grid,map<int,int>& lable,int count)
    {
        lable[i*grid[0].size()+j]=1;
        if(i>=1&&lable[(i-1)*grid[0].size()+j]!=1&&grid[i-1][j]==1)//向上
        {
            count=dfs(i-1,j,grid,lable,++count);
        }
        if(i+1<grid.size()&&lable[(i+1)*grid[0].size()+j]!=1&&grid[i+1][j]==1)//向下
        {
            count=dfs(i+1,j,grid,lable,++count);
        }
        if(j>=1&&lable[i*grid[0].size()+j-1]!=1&&grid[i][j-1]==1)//向左
        {
            count=dfs(i,j-1,grid,lable,++count);
        }
        if(j+1<grid[0].size()&&lable[i*grid[0].size()+j+1]!=1&&grid[i][j+1]==1)//向右
        {
            count=dfs(i,j+1,grid,lable,++count);
        }
        return count;
    }
    int maxAreaOfIsland(vector<vector<int>>& grid)
    {
        map<int,int>lable;
        int max=0,count=0;
        for(int i=0;i<grid.size();i++)
        {
            vector<int>line=grid[i];
            for(int j=0;j<line.size();j++)
            {
                count=1;
                if(lable[i*line.size()+j]!=1)//没访问过
                {
                    if(grid[i][j]==0)//0就跳过
                        continue;
                    count=dfs(i,j,grid,lable,count);
                    if(max<count)
                        max=count;
                }
                else
                    continue;
            }
        }
        return max;
    }
};
leedcode 695

改进:不需要标记数组,直接将走过的地方赋值成0,时间和空间都会节省下来

class Solution {
public:
    int dfs(int i,int j,vector<vector<int>>& grid,int count)
    {
        grid[i][j]=0;
        if(i>=1&&grid[i-1][j]==1)//向上
        {
            count=dfs(i-1,j,grid,++count);
        }
        if(i+1<grid.size()&&grid[i+1][j]==1)//向下
        {
            count=dfs(i+1,j,grid,++count);
        }
        if(j>=1&&grid[i][j-1]==1)//向左
        {
            count=dfs(i,j-1,grid,++count);
        }
        if(j+1<grid[0].size()&&grid[i][j+1]==1)//向右
        {
            count=dfs(i,j+1,grid,++count);
        }
        return count;
    }
    int maxAreaOfIsland(vector<vector<int>>& grid)
    {
        int max=0,count=0;
        for(int i=0;i<grid.size();i++)
        {
            vector<int>line=grid[i];
            for(int j=0;j<line.size();j++)
            {
                count=1;
                if(grid[i][j]==0)//0就跳过
                    continue;
                count=dfs(i,j,grid,count);
                if(max<count)
                    max=count;
            }
        }
        return max;
    }
};
leetcode 695

 

leetcode 200. 岛屿数量

和上面的一样,改成char,不需要标记数组,不需要统计每一块内的数量,统计不联通的数量即可

class Solution {
public:
    void dfs(int i,int j,vector<vector<char>>& grid)
    {
        grid[i][j]='0';
        if(i>=1&&grid[i-1][j]=='1')//向上
        {
            dfs(i-1,j,grid);
        }
        if(i+1<grid.size()&&grid[i+1][j]=='1')//向下
        {
            dfs(i+1,j,grid);
        }
        if(j>=1&&grid[i][j-1]=='1')//向左
        {
            dfs(i,j-1,grid);
        }
        if(j+1<grid[0].size()&&grid[i][j+1]=='1')//向右
        {
            dfs(i,j+1,grid);
        }
        return ;
    }
    int numIslands(vector<vector<char>>& grid) {
        int max=0,count=0;
        for(int i=0;i<grid.size();i++)
        {
            vector<char>line=grid[i];
            for(int j=0;j<line.size();j++)
            {
                if(grid[i][j]=='0')//0就跳过
                    continue;
                count++;
                dfs(i,j,grid);
                
            }
        }
        return count;
    }
};
leetcode 200

 

leetcode 17. 电话号码的字母组合

典型的深搜,要一眼看出来

class Solution {
public:
    vector<string>result;
    vector<char>vec;
    string dictionary(char a)
    {
        string str;
        if(a=='2')
            str="abc";
        if(a=='3')
            str="def";
        if(a=='4')
            str="ghi";
        if(a=='5')
            str="jkl";
        if(a=='6')
            str="mno";
        if(a=='7')
            str="pqrs";
        if(a=='8')
            str="tuv";
        if(a=='9')
            str="wxyz";
        return str;
    }
    string mk_str(int maxlen)
    {
        string tmp(maxlen, ' ');
        for(int i=0;i<maxlen;i++)
        {
            tmp[i]=vec[i];
        }
        return tmp;
    }
    void loop(string digs,int i,int maxlen)
    {
        if(i>=maxlen)
        {
            result.push_back(mk_str(maxlen));
            return;
        }
        string now=dictionary(digs[i]);
        for(int m=0;m<now.size();m++)
        {
            //cout<<"push:"<<now[m]<<endl;
            vec.push_back(now[m]);
            i++;
            loop(digs,i,maxlen);
            i--;
            //cout<<"pop :"<<vec.back()<<endl;
            vec.pop_back();
            
        }
        return;
    }
    vector<string> letterCombinations(string digits) {
        if (digits.size()==0)
            return result;
        loop(digits,0,digits.size());
        return result;
    }
};
leetcode 17

 

leetcode 22. 括号生成

深搜+剪枝

class Solution {
public:
    vector<char>tmp;
    vector<string>result;
    string char2string()
    {
        int maxlen=tmp.size();
        string ttmp(maxlen, ' ');
        for(int i=0;i<maxlen;i++)
        {
            ttmp[i]=tmp[i];
        }
        return ttmp;
    }
    void loop(int numA,int numB,int max)
    {
        if(numB>=max)//返回条件
        {
            string mystr=char2string();
            result.push_back(mystr);
            return;
        }
        if(numA>=max)//前括号已满
        {
            numB++;
            tmp.push_back(')');
            loop(numA,numB,max);
            tmp.pop_back();
            numB--;
        }
        else//前括号未满
        {
            if(numA>numB)
            {
                numA++;
                tmp.push_back('(');
                loop(numA,numB,max);
                tmp.pop_back();
                numA--;
                numB++;
                tmp.push_back(')');
                loop(numA,numB,max);
                tmp.pop_back();
                numB--;
            }
            else
            {
                numA++;
                tmp.push_back('(');
                loop(numA,numB,max);
                tmp.pop_back();
                numA--;
            }
        }
        return;
    }
    vector<string> generateParenthesis(int n) {
        loop(0,0,n);
        return result;
    }
};
leetcode 22

 

leetcode 39. 组合总和

class Solution {
public:
    vector<vector<int>> result;
    vector<int>tmp;
    void dfs(vector<int>& candidates, int target,int i)
    {
        if(target==0)//可能找到了结果
        {
            if(tmp.size()>0)//真的找到了结果
            {
                result.push_back(tmp);
                return;
            }
        }
        if(i>=candidates.size())//找到最后了
            return;
        if(candidates[i]>target)//超过去了
            return;
        for(int k=i;k<candidates.size();k++)
        {
            target=target-candidates[k];//
            tmp.push_back(candidates[k]);//入栈
            dfs(candidates,target,k);
            target=target+candidates[k];//还原
            tmp.pop_back();//出栈
        }
        return;
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        if(candidates.size()==0)
            return result;
        sort(candidates.begin(),candidates.end());//排序
        dfs(candidates,target,0);
        return result;
    }
};
leetcode39

 

78. 子集

class Solution {
public:
    vector<vector<int>>result;
    vector<int>tmp;
    void dfs(vector<int>& nums,int deepth,int maxD,int x)
    {
        if(x>nums.size())
            return;
        if(tmp.size()==maxD)
        {
            result.push_back(tmp);
            return;
        }
        for(int i=x;i<nums.size();i++)
        {
            tmp.push_back(nums[i]);
            deepth++;
            i++;
            dfs(nums,deepth,maxD,i);
            i--;
            deepth--;
            tmp.pop_back();
        }
        return;
    }
    vector<vector<int>> subsets(vector<int>& nums) {
        result.push_back(tmp);
        if(nums.size()==0)
            return result;
        result.push_back(nums);
        for(int i=1;i<nums.size();i++)
        {
            dfs(nums,0,i,0);
        }
        return result;
    }
};
leetcode 78

 

posted @ 2020-02-22 22:32  未名亚柳  阅读(157)  评论(0编辑  收藏  举报