常见搜索问题

深度优先算法

题目:695 岛屿的最大数量
给了一个01组成的数组,1为岛屿,求其中最大岛屿的面积。

解题
使用DFS+沉岛法,把搜索过了的岛屿下沉

class Solution {
    public int maxAreaOfIsland(int[][] grid) {
        //特判
        if(grid.length==0||grid[0].length==0)return 0;
        //DFS+沉岛思想
        //主函数遍历从所有点作为起点时,对其相连的面积做判断,找出最大的一块连续区域
        int ans = 0;
        for(int i = 0;i<grid.length;i++){
            for(int j = 0;j<grid[0].length;j++){
                if(grid[i][j]==1){
                    ans = Math.max(ans,dfs(grid,i,j));
                }
            }
        }
        return ans;

    }
    public int dfs(int[][] grid,int x,int y){
        //返回值为该块为起点的整个岛屿的大小
        //辅函数做递归,从主函数找到的第一块陆地开始,往其四周扩展,将这个岛屿的四周使用dfs的方式全部沉落
        //如果越界了,或者本身就是0,则返回0
        if(x<0||x>=grid.length||y<0||y>=grid[0].length||grid[x][y]==0)return 0;
        //否则说明该块为岛屿,下沉其和其周围的所有岛屿
        grid[x][y] = 0;
        int num = 1;
        num += dfs(grid,x-1,y);
        num += dfs(grid,x+1,y);
        num += dfs(grid,x,y-1);
        num += dfs(grid,x,y+1);
        return num;
    } 
}

剑指 Offer II 116. 朋友圈
题目:
给了一个数组,ij位置的元素表示i与j之间的关系,所有直接/间接认识的人组成了一个朋友圈,求一共有多少个朋友圈。

使用DFS+每个人是否加入朋友圈的一个一维数组实现

class Solution {
    public int findCircleNum(int[][] isConnected) {
        //特判
        if(isConnected.length==0||isConnected[0].length==0)return 0;
        //使用一个数组表示每一个元素是否有归属
        //使用DFS遍历所有元素,直至所有元素都有了自己的所属
        int cnt = 0;
        boolean used[] = new boolean[isConnected.length];
        for(int i =0;i<isConnected.length;i++){
            //遍历所有元素,如果它没有被遍历过,则从它开始找到所有属于它的圈子的
            if(used[i]==false){
                used[i] = true;
                dfs(used,isConnected,i);
                cnt++;
            }
            
        }
        return cnt;

    }

    public void dfs(boolean used[] ,int[][] isConnected,int x){
        for(int j = 0;j<isConnected[0].length;j++){
            if(isConnected[x][j]==1&&used[j]==false){
                used[j] = true;
                dfs(used,isConnected,j);
            }
        }
        return;
    }
}

417、大西洋、太平洋水流
给了一个矩阵,其中的元素表示每个位置的高度,求哪些位置放水可以流到两个洋?

解法:从每个点出发去看水能不能往低处流流入到两个洋比较耗时,不如直接从两个洋的水往高处流,看能能流到哪一些格子。看两个洋共同能流到的格子。

class Solution {
private:
    vector<vector<int>> ans;
    vector<int> direction{-1,0,1,0,-1};
public:
    vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {
        //特判
        if(heights.size()==0||heights[0].size()==0)return{};
        //水往高处流,从大陆的边界进行遍历,找到两个海域分别能到达的位置
        int m = heights.size(), n = heights[0].size();
        vector<vector<bool>> pacifit_reach(m,vector<bool>(n,false));
        vector<vector<bool>> atlantic_reach(m,vector<bool>(n,false));
        for(int i = 0;i<m;i++){
            // cout<<"i = "<<i<<" pacific"<<endl;
            dfs(heights,pacifit_reach,i,0);
            // cout<<"i = "<<i<<" atlantic"<<endl;
            dfs(heights,atlantic_reach,i,n-1);
        }
        for(int j = 0;j<n;j++){
            // cout<<"j = "<<j<<" pacific"<<endl;
            dfs(heights,pacifit_reach,0,j);
            // cout<<"j = "<<j<<" atlantic"<<endl;
            dfs(heights,atlantic_reach,m-1,j);
        }
        for(int i = 0;i<m;i++){
            for(int j =0;j<n;j++){
                if(atlantic_reach[i][j]==true&&pacifit_reach[i][j]==true){
                    ans.push_back(vector<int>{i,j});
                }
            }
        }
        return ans;


    }
    void dfs(vector<vector<int>>& heights,vector<vector<bool>>& can_reach,int x,int y){
        
        //从某块海域出发,dfs搜索其周围的所有自己可到达的,海水倒流
        //只有对可以到达的地方,才使用dfs来遍历
        if(can_reach[x][y]==true)return;
        can_reach[x][y] = true;
        cout<<"x = "<<x<<" y = "<<y<<endl;
        //继续向四个方向找
        for(int i = 0;i<4;i++){
            int cur_x = x+direction[i];
            int cur_y = y+direction[i+1];
            if(cur_x>=0&&cur_x<heights.size()&&cur_y>=0&&cur_y<heights[0].size()&&heights[cur_x][cur_y]>=heights[x][y])
                dfs(heights,can_reach,cur_x,cur_y);
        }
        
    
    }
};

257.二叉树的遍历
返回二叉树所有从根节点到叶节点的路径。

解法:使用dfs实现
注意中间一个重要的点:这里面的字符串的回溯感觉会比较麻烦,因此在往下一层传递参数的时候,就只是值传递,因此回到上一层的时候就不需要再从字符串中把东西抽出来。
在确保了下一层会有东西的时候,在函数中添加->

class Solution {
public:
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> ans;
        string sol;
        if(root==nullptr)return ans;
        dfs(root,ans,sol);
        return ans;

    }

    void dfs(TreeNode* cur,vector<string>& ans,string sol){
        //特判
        //如果为叶子节点,就将当前路径添加到结果中
        sol+=to_string(cur->val);
        if(cur->left==nullptr&&cur->right==nullptr){
            ans.push_back(sol);
        }
        //否则的话,继续dfs下面一层
        if(cur->left!=nullptr){
            dfs(cur->left,ans,sol+"->");
        }
        if(cur->right!=nullptr){
            dfs(cur->right,ans,sol+"->");
        }
        return;
    }
};

//Line 1034: Char 34: runtime error: addition of unsigned offset to 0x610000000040 overflowed to 0x610000000028 (stl_vector.h)
// SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/…/lib/gcc/x86_64-linux-gnu/9/…/…/…/…/include/c++/9/bits/stl_vector.h:1043:34
//出现了下标-1

注意⚠️
出现问题

  • Line 1034: Char 34: runtime error: addition of unsigned offset to 0x610000000040 overflowed to 0x610000000028 (stl_vector.h)
    SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/…/lib/gcc/x86_64-linux-gnu/9/…/…/…/…/include/c++/9/bits/stl_vector.h:1043:34
  • 一般是因为出现了下标-1
回溯法
  • 回溯法是优先搜索的特殊情况,需要记录节点状态的深度优先搜索。
  • 使用条件
    排列、组合、选择
  • 深度搜索 vs 回溯
    深度搜索:修改当前节点-递归求自节点
    回溯:修改当前节点-递归求子节点-回改当前节点状态
    深度遍历是不需要完全的从每个点出发、搜索每一种可能的。
    但是回溯基本上都是要使用一遍

79、单词搜索
给定一个由单词组成的矩阵,去遍历这个矩阵,如果字母都与其上下左右四个方向上的字母相连。给定一个字符串,看她能不能在字母矩阵中找到。

其中回溯体现的点在于使用了一个used数组,每次使用一个元素将其设置为used(每个元素只能用一遍,避免下一层调用时候再使用一遍)、使用完后将它的使用撤回

class Solution {
private:
    vector<int> direction{1,0,-1,0,1};
public:
    bool exist(vector<vector<char>>& board, string word) {
        //使用回溯的方法实现,来找从每个节点出发是否可以从深度遍历走到想要的字符串
        int m = board.size();
        int n = board[0].size();

        //特判
        if(m==0||n==0)return false;
        vector<vector<bool>> used(m,vector<bool>(n,false));
        for(int i = 0;i<board.size();i++){
            for(int j = 0;j<board[0].size();j++){
                if(traceback(board,used,word,0,i,j))
                    return true;
                
            }
        }
        return false;


    }

    bool traceback(vector<vector<char>>& board,vector<vector<bool>>& used,string word,int cur_p,int x,int y){
        //只有当前指针值相同时,才可以进入该函数
        //特判
        if(x<0||x>=board.size()||y<0||y>=board[0].size()||used[x][y]==true||word[cur_p]!=board[x][y]){
            return false;
        }
        if(cur_p+1==word.length())return true;
        //从当前节点出发,然后按照上下左右的方向去找是否能构成
        used[x][y] =true;
        for(int i=0;i<4;i++){
            int cur_x = x + direction[i];
            int cur_y = y+direction[i+1];
            if(traceback(board,used,word,cur_p+1,cur_x,cur_y)==true)
                return true;
        }
        used[x][y] = false;
        return false;
    }
};

51、N皇后
给了一个N*N的棋盘,往上放N个皇后,两个皇后不能在同一行,同一列,同一斜线。求有多少种算法。

解法:使用回溯算法,遍历所有的可能。
注意:其中希望能高效的求出是否有两个元素会在同一条斜线上,因此需要使用一个集合set来记录哪一些斜线上面已经有值了。

class Solution {
private:
    vector<vector<string>> ans;
public:
    vector<vector<string>> solveNQueens(int n) {
        //特判
        if(n==0)return {};
        //使用回溯算法

        //定义已经使用向量
    
        vector<bool> used(n,false);
        vector<string> sol(n,string(n,'.'));
        //标明两个斜线上面的数组
        auto diagonals1 = unordered_set<int>();
        auto diagonals2 = unordered_set<int>();

        //定义返回列表
        traceback(n,0,used,sol,diagonals1,diagonals2);
        return ans;
            


    }

    void traceback(int n,int level, vector<bool>& used,vector<string> sol,unordered_set<int>& diagonals1,unordered_set<int>& diagonals2){
        //特判
        if(level==n){
            ans.push_back(sol);
            return;
        }
        for(int j = 0;j<n;j++){
            //否则的化为当前行寻找合适的位置
            if(used[j]==false){
                if(diagonals1.find(level-j)!=diagonals1.end())continue;
                if(diagonals2.find(level+j)!=diagonals2.end())continue;
                diagonals1.insert(level-j);
                diagonals2.insert(level+j);
                used[j]=true;
                sol[level][j] = 'Q';
                traceback(n,level+1,used,sol,diagonals1,diagonals2);
                sol[level][j] = '.';
                used[j]=false;
                diagonals1.erase(level-j);
                diagonals2.erase(level+j);
            }
        }
    }
};

使用了unordered_set,其基本操作有find、insert、erase等。
find如果找不到元素,会返回set的end。

广度优先算法

使用队列实现。
适用于找最短路径等。
与深度优先都可以实现可达性问题,即一个点能否到达另一个点。

934、最短的桥
给了一个由01组成的矩阵,其中0表示水,1表示陆地。其中有且仅有两块陆地,求最少需要填多少块陆地来使得两个岛屿联通。

解答:实际上就是求两个岛屿之间的最短的路径长度。
使用DFS先求出一整个岛屿,将其放进队列中去,然后再从这个队列出发,使用BFS一直遍历到另外一个岛屿,其中的步数就是最短路径长度。

注意:其中很巧妙的将已经遍历过的岛屿和水都使用2来标记,使得在DFS寻找整个岛屿(类似于沉岛的思想)和使用BFS来找另一个岛屿的时候都不会出现有回头路的可能。而且在BFS找最短路的时,由于如果有岛屿遍历到了为2的位置,说明前面已经有人走过这了,此时遍历这个的人已经是慢一步的,因此不需要继续了,可以剪枝。

class Solution {

private:
    vector<int> direction{-1,0,1,0,-1};
    int m,n;
public:
    int shortestBridge(vector<vector<int>>& grid) {
        //找两座岛之间的最短距离

        m = grid.size();
        n = grid[0].size();
        //先使用DFS方法找到一个岛,把它的坐标存入到队列里面
        queue<pair<int,int>> island1;
        bool flag = false;
        for(int i = 0;i<m&&flag==false;i++){
            for(int j = 0;j<n&&flag==false;j++){
                if(grid[i][j]==1){
                    getisland1(grid,island1,i,j);
                    flag = true;
                }
            }
        }
        
        //使用BFS的方法,去找两座岛之间的最小距离
        //从islands1出发,BFS搜索,直至第一个找到值为1的格子
        int distance =0;
        while(!island1.empty()){
            distance++;
            int num = island1.size();
            for(int i = 0;i<num;i++){
                auto [x,y]= island1.front();
                island1.pop();
                //朝四个方向找
                for(int j=0;j<4;j++){
                    int cur_x = x+direction[j];
                    int cur_y = y+direction[j+1];
                    if(cur_x>=0&&cur_x<m&&cur_y>=0&&cur_y<n){
                        if(grid[cur_x][cur_y]==1)return distance-1;
                        if(grid[cur_x][cur_y]==2)continue;
                        island1.push({cur_x,cur_y});
                        grid[cur_x][cur_y]=2;
                    }
                }
            }
        }
        return 0;

        

    }

    void getisland1(vector<vector<int>>& grid,queue<pair<int,int>>& island1,int x,int y){
        //特判
        //如果定位已经超出了边界||不是陆地,就返回
        if(x<0||x>=m||y<0||y>=n||grid[x][y]==0||grid[x][y]==2)return;
        //否则将其加入到队列中,并且递归判断其四周的点是否为小岛
        island1.push({x,y});
        grid[x][y] = 2;
        for(int i = 0;i<4;i++){
            int cur_x = x+direction[i];
            int cur_y = y+direction[i+1];
            getisland1(grid,island1,cur_x,cur_y);
        }
        return;
    }
};

310

class Solution {
public:
    vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
        if(n==2)return edges[0];
        vector<vector<int>> edges_pic(n,vector<int>(n,0));
        for(int i = 0;i<edges.size();i++){
            int x= edges[i][0];
            int y = edges[i][1];
            edges_pic[x][y] = 1;
            edges_pic[y][x] = 1;
        }
        //给一棵树的图,求这棵树的最小高度
        auto ans = unordered_map<int,vector<int>>();
        //从每个节点出发,找到每个根节点对应的高度
        for(int i= 0;i<n;i++){
            queue<int> queue;
            queue.push(i);
            unordered_set<int> set;
            set.insert(i);
            int level = bfs(n,edges_pic,set,queue,i);
            ans[level].push_back(i);
        }
        for(int i =0;i<n;i++){
            //遍历所有,找到最小的n值
            if(ans.count(i)!=0)return ans[i];
        }
        return vector<int>{0};


    }
    int bfs(int n, vector<vector<int>>& edges,unordered_set<int> set,queue<int>& queue,int cur_i){
        cout<<"进入函数,cur_i="<<cur_i<<endl;
        //按照bfs的方式按层搜索节点,直至队列中没有元素
        int level = 0;
        while(!queue.empty()){
            level++;
            if(set.size()==n)break;

            
            // cout<<"level="<<level<<endl;
            //还有元素时,就批量处理这一组元素
            int queue_n = queue.size();
            // cout<<"queue_n = "<<queue_n<<endl;
            for(int i =0;i<queue_n;i++){
                int point = queue.front();
                // cout<<"queue.front执行完,point ="<<point<<endl;
                queue.pop();
                // cout<<"queue.pop执行完"<<endl;
                //从这个元素出发,找与他相连但是没有被遍历过的界定啊
                for(int j= 0;j<n;j++){
                    // cout<<"j = "<<j<<endl;
                    // cout<<"edge  ="<<edges[point][j]<<endl;
                    if(edges[point][j]==1&&set.count(j)==0){
                        //相连,且这个节点不在set中
                        // cout<<"符合条件,要加入set的有"<<j<<endl;
                        queue.push(j);
                        
                        set.insert(j);
                        // cout<<"set.size = "<<set.size()<<endl;
                    }
                }
            }
        }
        // cout<<"level = "<<level<<endl;
        return level;
    }
};

方法应该没问题,但是43个用例时超时了

修改
注意到越在这个图中央的点约有可能是拥有最小高度的树的root节点,因此类似剥洋葱的方法,其中有出度为1的节点为当前的最外面一层的节点。需要把这个节点剥掉,一层一层找到最里面的节点,那么从这个/这些节点出发,往外面走的最长路径最小,整棵树的高度越小。

class Solution {
public:
    vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
        //使用剥洋葱的方法,其中出度为1的节点表示洋葱中的最外一层。
        //首先处理边节点,然后找出所有当前的出度为1的节点


        //邻接节点map
        unordered_map<int,vector<int>> edge_map;
        //每个节点的出度
        vector<int> degree(n,0);

        //特判
        if(n==1){
            return vector<int>{0};
        }
        for(vector<int> edge:edges){
            int v0 = edge[0];
            int v1 = edge[1];
            edge_map[v0].push_back(v1);
            edge_map[v1].push_back(v0);
            degree[v0]++;
            degree[v1]++;
        }
        //所有出度为1的节点组成的队列
        queue<int> edge_queue;
        //找出所有出度为1的节点
        for(int i =0;i<n;i++){
            if(edge_map[i].size()==1){
                edge_queue.push(i);
            }
        }
        //从当前这些节点出发,进行bfs的搜索,其中最后一层剩下的就是
        return bfs(edge_queue,degree,edge_map);
    }
    vector<int> bfs(queue<int> edge_queue,vector<int> degree,unordered_map<int,vector<int>> edge_map){
        vector<int> ans;
        while(!edge_queue.empty()){
            //只要它不为空就可以
            int num = edge_queue.size();
            cout<<"num = "<<num<<endl;
            //将里面当前的所有元素加入到一个vector中去,可能是返回值
            ans.clear();
            for(int i =0;i<num;i++){
                //取当前队列的头
                int cur_v = edge_queue.front();
                // cout<<"cur_v ="<<cur_v<<endl;
                edge_queue.pop();
                degree[cur_v]--;
                ans.push_back(cur_v);
                //找与它相邻的节点,将他们的度--;
                for(int v:edge_map[cur_v]){
                    degree[v]--;
                    if(degree[v]==1)
                    edge_queue.push(v);
                }
            }
        }
        return ans;
    }

};


//queue的操作是push
//set的插入是insert

各种集合的操作整理

//queue的操作是push
//set的插入是insert

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
previous up contents next C 语言常见问题集 原著:Steve Summit 翻译:朱群英, 孙 云 修订版 0.9.4, 2005年6月23日 版权所有 © 2005 * 目录 * 1. 前言 * 2. 声明和初始化 o 2.1 我如何决定使用那种整数类型? o 2.2 64 位机上的 64 位类型是什么样的? o 2.3 怎样定义和声明全局变量和函数最好? o 2.4 extern 在函数声明中是什么意思? o 2.5 关键字 auto 到底有什么用途? o 2.6 我似乎不能成功定义一个链表。我试过 typedef struct { char *item; NODEPTR next; } *NODEPTR; 但是编译器报了错误信息。难道在C语言中一个结构不能包含指向自己的指针吗? o 2.7 怎样建立和理解非常复杂的声明?例如定义一个包含 N 个指向返回指向字符的指针的函数的指针的数组? o 2.8 函数只定义了一次, 调用了一次, 但编译器提示非法重定义了。 o 2.9 main() 的正确定义是什么? void main() 正确吗? o 2.10 对于没有初始化的变量的初始值可以作怎样的假定?如果一个全局变量初始值为 ``零", 它可否作为空指针或浮点零? o 2.11 代码 int f() { char a[] = "Hello, world!";} 不能编译。 o 2.12 这样的初始化有什么问题?char *p = malloc(10); 编译器提示 ``非法初始式" 云云。 o 2.13 以下的初始化有什么区别?char a[] = "string literal"; char *p = "string literal"; 当我向 p[i] 赋值的时候, 我的程序崩溃了。 o 2.14 我总算弄清除函数指针的声明方法了, 但怎样才能初始化呢? * 3. 结构、联合和枚举 o 3.1 声明 struct x1 { ...}; 和 typedef struct { ...} x2; 有什么不同? o 3.2 为什么 struct x { ...}; x thestruct; 不对? o 3.3 一个结构可以包含指向自己的指针吗? o 3.4 在 C 语言中实现抽象数据类型什么方法最好? o 3.5 在 C 中是否有模拟继承等面向对象程序设计特性的好方法? o 3.6 我遇到这样声明结构的代码: struct name { int namelen; char namestr[1];}; 然后又使用一些内存分配技巧使 namestr 数组用起来好像有多个元素。这样合法和可移植吗? o 3.7 是否有自动比较结构的方法? o 3.8 如何向接受结构参数的函数传入常数值? o 3.9 怎样从/向数据文件读/写结构? o 3.10 我的编译器在结构中留下了空洞, 这导致空间浪费而且无法与外部数据文件进行 "二进制" 读写。能否关掉填充, 或者控制结构域的对齐方式? o 3.11 为什么 sizeof 返回的值大于结构的期望值, 是不是尾部有填充? o 3.12 如何确定域在结构中的字节偏移? o 3.13 怎样在运行时用名字访问结构中的域? o 3.14 程序运行正确, 但退出时却 ``core dump''了,怎么回事? o 3.15 可以初始化一个联合吗? o 3.16 枚举和一组预处理的 #define 有什么不同? o 3.17 有什么容易的显示枚举值符号的方法? * 4. 表达式 o 4.1 为什么这样的代码: a[i] = i++; 不能工作? o 4.2 使用我的编译器,下面的代码 int i=7; printf("%d\n", i++ * i++); 返回 49?不管按什么顺序计算, 难道不该打印出56吗? o 4.3 对于代码 in
请问在openlayers中如何删除Layer中的marker 3 在层中加了一个标记怎么永久的存到地图上 3 OpenLayers 如何设死地图边界 3 谁写过openlayers解析xml 3 openlayer.popup 3 OpenLayers 怎么做字段标注 4 字段标注不是用OL做的,而是你在SLD中定义用数据表的哪个字段做标签就可以了 4 OpenLayers 中画最短轨迹 4 使用TileCache配合OpenLayers 4 openlayers如何准确测距 9 openlayers简单实用例子 9 关于TileCache函数 13 openlayers 有函数说明的类图 14 go 14 Maker 一多,客户端就死掉 15 OpenLayers 怎么实现 AJAX 16 openlayer 要怎么研究才会应用得比较自如 16 改良OpenLayers的Popup 16 在openlayers的地图中要添加地图搜索功能一般采用什么方法 17 openlayers中如何访问geoserver发布的图片 18 什么是TMS? 18 怎样设置瓦片的大小 18 画一条线,数据量太大,怎么办? 18 怎么在图层上动态画点 20 GeoExt集成google map ,地图偏移 21 用JavaScript为OpenLayers.Marker的加上单击显示详细信息的功能 21 改良OpenLayers的MousePostion 25 使用OpenLayers实现一个在鼠标点击处添加标记的效果 27 openlayers 利用google maps的卫星地图 29 openLayers集成google map ,点标注错位 30 openlayers可以做出谷歌效果的地图吗? 31 用OpenLayers API和类来画点、线、面 32 OGC标准术语介绍WMS、WFS、WCS 35 如何控制地图的放缩 37 openLayers链接WMS的代码探讨 37 openlayers 2.5 矢量层在ie下闪烁的问题 38 openLayers 在地图上添加一个点并保存 39 openLayers 各个参数的意义 42 geoserver能搞出这种风格的图来吗? 43 关于SLD的线切割后的设置 43 GEOSERVE 标注铁路,使用 SLD 44 geoserver 发布.shp 中文乱码问题 怎么解决啊 45 Geoserver怎么连postGreSql 数据库 48 Geoserver连Oracle Spatial 52 GeoServer架构浅谈 53 Geoserver发布地图无法显示问题 57 WebGIS相关的OpenGIS规范 58 geoserver中地图以外的区域以自定义图片填充 62 怎样修改 geoServer 的用户名密码 65 GeoServer中的WMS服务生成的png图片背景色为透明 65 比例尺 65 需不需要一个layer对应一个store 66 如何部署shp 66 用GeoWebCache后Marker错位 66 标签太大导致不能显示? 67 geoserver把两个shapefile格式的图叠 67 GeoServer 能够集成 Google Map? 68 gwc地图切片的缓存路径在web.xml中设置么 68 如何实现地图查询? 68 sld文件怎么用 69 在sld中怎么控制路名的间隔? 69

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值