最短时间学会基于C++实现DFS深度优先搜索

目录
  • 前言
  • 1.迷宫找出口,区分dfs,bfs:
  • 一、DFS经典放牌可能组合
  • 二、leetcode 员工的重要性
  • 三、leetcode 图像渲染
  • 四、leetcode 被围绕的区域
  • 五、岛屿数量
  • 六、 小练习:岛屿的最大面积
  • 总结

前言

同学们肯定或多或少的听到过别人提起过DFS,BFS,却一直都不太了解是什么,其实两个各为搜索算法,常见使用 深度优先搜索(DFS) 以及 广度优先搜索(BFS) ,今天我们就来讲讲什么是深度优先搜索,深度优先就是撞到了南墙才知道回头,才会往上一层返回。

1.迷宫找出口,区分dfs,bfs:

dfs: 深度优先我们可以看出他一次只往一个方向走,直到撞到了才会返回上一层去尝试其他结果,图片为上左下右的去走

BFS:广度优先就是尝试该位置的旁边的所有可能,再把所有可能的能走到的所有可能继续走.撞到了就停止,如果全部可能都'碰壁'表示从该位置无法走到终点

对比两个遍历方式,相信大家有了初步的认识,让我们接下来看看这道题

一、DFS经典放牌可能组合

题目:我们手上有编号为1~3的三个扑克牌,我们要放到编号为1 ~ 3的盒子当中,并且每个盒子中只放一张牌,问我们有多少种方法。

聪明的同学可能想一想就知道是6种了,但是当我们的要用计算机表达时我们要如何处理呢?题目虽简单,所以我们借这道题来看看DFS如何解题.

方法一: 暴力循环,三层循环嵌套,判断每张牌只用一次,这种方法简单粗暴.

方法二: 深度搜索,我们选择把按照从小到大的依次尝试,在第一个盒子先开始放1,这时我们剩下两张牌,对第二个盒子来说,我们从小到大放,放2,第三个盒子只有3了,第一种放法就出来了 1 2 3。
此时我们全部牌都放完了,然后我们这时候就是撞到了南墙了,我们就开始回收3,回收3的时候如果我们重复放3到第三个盒子就和之前重复了,所以我们再回收2,这时我们就可以把3放到第二个盒子,把2放在第三个盒子,第二种放法就出来了,1 3 2。

这时我们放完了之后再回收,我们回收了2,3后,1的所有可能我们就已经遍历完了,这个时候我们就回收1,这时我们就可以开始把2放到第一个盒子,这时我们还有1 ,3 ,我们按之前的从小到大的原则,把1放入第二个盒子,剩一个3放在第三个盒子,这时的第三种放法 2 1 3出来了

同理我们收两张牌就有组合2 3 1 ,同理3 1 2 ,2 31 ,这样我们的6种出来了,即:我们站在一个盒子,我们按照我们手中的牌,从小到大依次尝试,即我们有一个循环,从第一张牌开始

//处理第index个盒子 _ - - 并行递归,n有多大我们就调用多少次
DFS(vector<int>& box,int index,vector<int>& visited,int n)
{//box为盒子,index为当前盒子,visited为标记哪张牌用了的数组,n为处理几张牌
	if(index == n+1)//每一个盒子都有牌了
	{
		return;
	}
	for(int i =1;i<n;++i)
	{
		if(visited[i]==0)
		{
			//表示没有用过的牌就可以放在当前的盒子当中
			box[index] = i;//当前的盒子放这张牌
			visited[i] =1 ;
			//这里的逻辑就是我们站在一个盒子,我们按照我们手中的牌,从小到大依次尝试
			//到这里我们就处理下一个盒子
			DFS(box,index+1,visited,n);
			//一种方法完成,我们就回收牌
			visited[i]=0;//标记成0就可以再次使用啦!
		}
	}
}

下面这个是测试n张牌,n个盒子的时候,我们所有的可能,可以自行粘贴复制到编辑器当中测试,请自行输入n

void DFS(int index, int n, vector<int>& box, vector<int>& visited)
{
	//处理当前的盒子

	//我们这里打印看看每个盒子装的都是什么
	if (index == n + 1)
	{
		for (int i=1;i<box.size();++i)
			cout << box[i] << " ";
		cout << endl;

		//表示每个盒子我们都已经放满了东西,我们就可以返回上一层
		return;
	}

	//每个盒子都要用n张牌来看看是否能够使用,按照我们从小到大使用的规定原则
	for (int i = 1; i <= n; ++i)
	{
		//表示牌没有被用过,可以使用
		if (visited[i] == 0)
		{
			box[index] = i;//表示在看到index个盒子的时候,我们用第i张牌放入

			visited[i] = 1;//标记当前牌已经被使用
			//走到这里我们当前这个盒子该干的事情已经干完了,我们就可以处理下一个盒子

			DFS(index + 1, n, box, visited);
			//表示所有的牌都已经放入并且返回,这时我们回收牌
			visited[i] = 0;
		}
	}
}
int main()
{
	int n;
	vector<int> box;
	vector<int> vistied;
	cin >> n;
	box.resize(n + 1, 0);
	vistied.resize(n + 1, 0);
	//这里的1是我们当前走到盒子,n是我们有多少牌,boxs是我们用来存放的盒子,
	//visited是用来确定是否访问过的标记矩阵
	DFS(1, n, box, vistied);
	return 0;
}

刚开始接触DFS有时候会思考一些奇奇怪怪的问题,这个时候大家应该都去调试调试,一开始的问题一定是要解决的!!!

总结归纳:
深度优先搜索的关键是解决当下应该怎么做,下一步的做法和当下的做法是一样的。当下的做法如何做到尝试每一种可能,我们用for循环遍历,对于每一种可能的确定后,我们继续下一步,当前的可能等到从下一步会退之后再处理
DFS常见的模型:
DFS(当前这一步的逻辑)
{
1.判断边界,是否已经撞到墙了:向上回退
2.尝试当下的每一种可能
3.确定一种可能之后,继续下一步,DFS(下一步)
}

二、leetcode 员工的重要性

员工的重要性

/*
// Definition for Employee.
class Employee {
public:
    int id;
    int importance;
    vector<int> subordinates;
};
*/

class Solution {
public:
    int getImportance(vector<Employee*> employees, int id) {

    }
};

题目的分析,题目给我们的信息就是给到一个id,要求他的直系下属和直系下属的直系下属的importance(重要度),并且vector<Employee*> employees,给我们一个保存员工的数据结构,我们可以先将id和他的重要度绑定起来(哈希表um),这样我们用DFS遍历的时候,就可以先处理当前id,每一个id都要处理他的vector subordinates(这个是他的直系员工的id),再去遍历当前id的直系下属.

for(int id: um[id]->subordinates)
        {
            //对于当前我们需要sum加上加上当前id的重要度
            sum += um[id]->importance;
            //遍历当前id的所有直系下属
            DFS(id,um,sum);
        }

// 题目答案:
class Solution {
public:
    void DFS(int id,unordered_map<int,Employee*>& um,int& sum)
    {
        //对于每一个id,下属的id都会有属于他们的vector<int> subordinates;
        //所以我们都要去遍历当前id的subordinates
        for(int id: um[id]->subordinates)
        {
            //对于当前我们需要sum加上加上当前id的重要度
            sum += um[id]->importance;
            //遍历当前id的直系下属(**一路走到黑**),统计完的结果放到sum当中
            DFS(id,um,sum);
        }
    }

    int getImportance(vector<Employee*> employees, int id) {
        //单个员工 id ,返回这个员工和他所有下属的重要度之和。
        //DFS:深度遍历这个员工的旗下所有重要度之和,这题适合一条路走到黑
        //因为在vector中的查找都是O(N)的时间复杂度,我们选择用哈希表,并且将id与员工的指针建立映射,因为我们在DFS中要使用到用id找到员工
        unordered_map<int,Employee*> um;
        for(Employee* e : employees)
        {
            //将employees的数据导入us(哈希表中)
            um[e->id] = e;
        }
        int sum = um[id]->importance;//提前加上当前id的重要度
        //dfs是遍历当前id的subordinates的重要度
        DFS(id, um,sum);
        return sum;
    }
};

这道题之后实际上后面的题目也都是类似的,大家从这道题开始可以尝试自己写一写,再看看我的代码解析,这样帮助理解!

三、leetcode 图像渲染

733. 图像渲染

这题实际上用bfs,dfs都可以,这里我们讲的是dfs,所以我们用dfs的方式解决,一开始我的想法是,遍历每一个位置的上下左右,将合法的位置并且是旧颜色的改成新颜色.

注:方向矩阵的概念:

int arr[4][2] ={{1,0},{0,1},{-1,0},{0,-1}};//方向矩阵
    void DFS(vector<vector<int>>& image, int curX, int curY, int newColor,int row ,int col,int oldcolor)
    {
        image[curX][curY] = newColor;//上色
        //遍历 (sr,sc)的上下左右 -- 我们可以设置一个全局的方向矩阵
        for(int i=0;i<4;++i)
        {
            //(newX,newY)就是该点的上下左右了
            int newX = curX+arr[i][0];
            int newY = curY+arr[i][1];
            if(newX<0||newX>=row
            ||newY<0||newY>=col)
            continue;//表示新的坐标越界了不符合要求,跳过

            //走到这里表示新的坐标没有问题,如果是就颜色我们就上色
            if(image[newX][newY] == oldcolor)
            {
                //当前的点处理完,我们处理下一个点
                DFS(image,newX,newY,newColor,row,col,oldcolor);
            }
            else
            continue;
        }
    }

但是这样子会有一个问题,当测试用例为新颜色和旧颜色相同的时候就会变成了死递归,所以我们少不了用标记矩阵,将我们走过的位置标记了他就不会重复走了。

以下为本道题的全部代码

int arr[4][2] ={ { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };
class Solution {
public:
    void DFS(vector<vector<int>>& image, int curX, int curY, int newColor,vector<vector<int>>& visited,int row ,int col,int oldColor)
    {
        //给当前位置染色
         image[curX][curY] = newColor;
         //标记当前位置已经使用了
         visited[curX][curY]=1;

        //遍历 (sr,sc)的上右下左 -- 我们可以设置一个全局的方向矩阵
        for(int i=0;i<4;++i)
        {
            //(newX,newY)就是该点的上下左右了
            int newX = curX+arr[i][0];
            int newY = curY+arr[i][1];
            //判断新坐标是否合法
            if(newX<0 || newX>=row
            || newY<0 || newY>=col)
            continue;

            //如果是没有访问过的并且是旧颜色就递归这个点的周围
            if(visited[newX][newY] == 0 &&
               image[newX][newY] == oldColor)
                 DFS(image,newX,newY,newColor,visited,row,col,oldColor) ; 

        }
    }
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
    //我们这道题也可以用BFS,DFS做都没问题,我们这里讲到DFS,所以就用DFS的思路解决
        int row = image.size();
        int col = image[0].size();
        int oldColor =image[sr][sc];
        //初始化标记矩阵,没访问过的置成0
        vector<vector<int>> visited(row,vector<int>(col,0));
        DFS(image,sr,sc,newColor,visited,row,col,oldColor);
        return image;
    }
};

四、leetcode 被围绕的区域

130. 被围绕的区域

本题就是想将全部没有与外围一圈O联通的O换成X,与外界连通的O不做改变
思路:拿到这样一道题,我们要将与外界O相连的O全部遍历到,所以会用到深度优先搜索,那么我们就可以从矩阵的外围一圈(第一行,最后一行,第一列,最后一列)出发,将外围的每一个O都深度搜索,将搜索到的O(即与外界相连的先换成#)
最后再将O换成#,将#换回O。当然也可以用标记矩阵来写,都是可以的,这里两种方法都写出来看看

1.不使用标记矩阵

int arr[4][2] ={ { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };
class Solution {
public:
    void DFS(vector<vector<char>>& board,int row,int col,int curX,int curY)
    {
        //当前点就是联通的‘O'
        board[curX][curY] ='#';
        for(int i =0;i<4;++i)
        {
            int newX = curX+arr[i][0];
            int newY = curY+arr[i][1];
            if(newX<0||newX>=row
            ||newY<0||newY>=col)
            continue;
            if(board[newX][newY]=='O')
            DFS(board,row,col,newX,newY);
        }
    }
    void solve(vector<vector<char>>& board) {
        //我们可以从每一个边界的O出发,链接的O就是不用改的,其他的都是要改成‘X'的
        //但是我们可以通过修改与外面相连的O暂时修改#,就不需要标记矩阵了
        int row =board.size();
        int col=board[0].size();
        for(int i=0;i<row;++i)
        {
            if(board[i][0] =='O')
            DFS(board,row,col,i,0);
            if(board[i][col-1] =='O')
            DFS(board,row,col,i,col-1);
        }
        for(int j =0;j<col;++j)
        {
            if(board[0][j]=='O')
            DFS(board,row,col,0,j);
            if(board[row-1][j]=='O')
            DFS(board,row,col,row-1,j);
        }
        for(int i =0;i<row;++i)
        {
            for(int j =0;j<col;++j)
            {
                if(board[i][j]=='O')
                board[i][j]='X';
                if(board[i][j]=='#')
                board[i][j]='O';
            }
        }
        return ;
    }
};

2.使用标记矩阵

int arr[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
class Solution {
public:
    void DFS(vector<vector<int>>& visited,vector<vector<char>>& board,int row,int col,int curX ,int curY)
    {
        //与外界联通的还是O,我们标记为1
        visited[curX][curY] = 1;

        for(int i =0;i<4;++i)
        {
            int newx = curX+arr[i][0];
            int newy = curY+arr[i][1];
            if(newx<0||newx>=row||
            newy<0||newy>=col)
            continue;
            //没有被访问过的位置(防止重复递归)&& 为O的位置我们才递归
            if(visited[newx][newy]==0&&
            board[newx][newy]=='O')
            {
                DFS(visited,board,row,col,newx,newy);
            }
        }
    }
    void solve(vector<vector<char>>& board) {
        //思路:我们从周围的O出发,与边界O DFS都能获取到的位置我们都可以做个标记
        //最后将标记的不动,没标记的换成'X'(内陆)。
        int row = board.size();
        int col=board[0].size();
        vector<vector<int>> visited(row,vector<int>(col,0));
        //遍历周围为O的位置
        //两列
        for(int i =0;i<row;++i)
        {
            if(board[i][0]=='O')
            DFS(visited,board,row,col,i,0);
            if(board[i][col-1]=='O')
            DFS(visited,board,row,col,i,col-1);
        }
        //两行
        for(int j =0;j<col;++j)
        {
            if(board[0][j]=='O')
            DFS(visited,board,row,col,0,j);
            if(board[row-1][j]=='O')
            DFS(visited,board,row,col,row-1,j);
        }
        //最后将没有标记的O换成X,标记了的不变
        for(int i =0;i<row;++i)
        {
            for(int j =0;j<col;++j)
            {
                if(visited[i][j]==0)
                board[i][j] = 'X';
                cout<<visited[i][j];
            }
        }
    }
};

五、岛屿数量

200. 岛屿数量

有了前面题的基础,对于这道题可谓是信手拈来,详情请看注释:

int arr[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
class Solution {
public:
    void DFS(vector<vector<int>>& visited,vector<vector<char>>& grid,int row,int col,int curx,int cury)
    {
        //将当前位置标记为走过
        visited[curx][cury]=1;
        for(int i =0;i<4;++i)
        {
            int newx = curx+arr[i][0];
            int newy = cury+arr[i][1];
            if(newx<0||newx>=row||newy<0||newy>=col)
                continue;
            if(grid[newx][newy]=='1'&&visited[newx][newy]==0)
            DFS(visited,grid,row,col,newx,newy);
        }
    }
    int numIslands(vector<vector<char>>& grid) {
        //这道题其实也是用BFS,DFS都可以解,用DFS的话我的思路是从第一个开始遍历,遇到一个visited没有访问过的1就去遍历他的上下左右,将他周围的1都遍历,在将次数加一
        int row =grid.size();
        int col=grid[0].size();
        int count =0;
        vector<vector<int>> visited(row,vector<int>(col,0));
        for(int i =0;i<row;++i)
        {
            for(int j =0;j<col;++j)
            {
                if(visited[i][j]==0&&grid[i][j]=='1')
                {
                    DFS(visited,grid,row,col,i,j);
                    count++;
                }
            }
        }
        return count;
    }
};

六、 小练习:岛屿的最大面积

695. 岛屿的最大面积

这道题留给大家作为一个小练习,有了前面的基础,相信这道题想必不是问题!!

总结

回溯思想DFS一些难度较大的题一起讲!!DFS的学习时要注意多调试,想清楚了再下手写,这样往往能够事半功倍

到此这篇关于最短时间学会基于C++实现DFS深度优先搜索的文章就介绍到这了,更多相关C++ DFS深度优先搜索内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • python 递归深度优先搜索与广度优先搜索算法模拟实现

     一.递归原理小案例分析 (1)# 概述 递归:即一个函数调用了自身,即实现了递归 凡是循环能做到的事,递归一般都能做到! (2)# 写递归的过程 1.写出临界条件 2.找出这一次和上一次关系 3.假设当前函数已经能用,调用自身计算上一次的结果,再求出本次的结果 (3)案例分析:求1+2+3+...+n的数和 # 概述 ''' 递归:即一个函数调用了自身,即实现了递归 凡是循环能做到的事,递归一般都能做到! ''' # 写递归的过程 ''' 1.写出临界条件 2.找出这一次和上一次关系 3.假设

  • C#深度优先搜索算法

    本文实例为大家分享了C#深度优先搜索算法的具体代码,供大家参考,具体内容如下 //论文要用到其改进算法,在此先demo测试一下 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DFS { class Program { public int[,] map = new int[100, 100];

  • Java编程实现基于图的深度优先搜索和广度优先搜索完整代码

    为了解15puzzle问题,了解了一下深度优先搜索和广度优先搜索.先来讨论一下深度优先搜索(DFS),深度优先的目的就是优先搜索距离起始顶点最远的那些路径,而广度优先搜索则是先搜索距离起始顶点最近的那些路径.我想着深度优先搜索和回溯有什么区别呢?百度一下,说回溯是深搜的一种,区别在于回溯不保留搜索树.那么广度优先搜索(BFS)呢?它有哪些应用呢?答:最短路径,分酒问题,八数码问题等.言归正传,这里笔者用java简单实现了一下广搜和深搜.其中深搜是用图+栈实现的,广搜使用图+队列实现的,代码如下:

  • C语言通过深度优先搜索来解电梯问题和N皇后问题的示例

    N皇后问题 问题描述: 在n×n格的棋盘上放置彼此不受攻击的n个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不妨在同一行或同一列或同一斜线上. 需求输入: 给定棋盘的大小n (n ≤ 13) 需求输出: 输出有多少种放置方法. #include <stdio.h> #include <math.h> #define MAX 101 int total = 0; char m[MAX][MAX

  • C语言实现图的遍历之深度优先搜索实例

    DFS(Depth-First-Search)深度优先搜索算法是图的遍历算法中非常常见的一类算法.分享给大家供大家参考.具体方法如下: #include <iostream> #include <algorithm> #include <iterator> using namespace std; #define MAX_VERTEX_NUM 10 struct Node { int adjvex; struct Node *next; int info; }; typ

  • JS实现深度优先搜索求解两点间最短路径

    本文实例为大家分享了JS实现深度优先搜索求解两点间最短路径的具体代码,供大家参考,具体内容如下 效果: 找出图里点到点最短路径,并打印轨迹 图片如下所示: 代码: const map = [ [0, 1, 1, 0, 1], [1, 0, 0, 1, 0], [1, 0, 0, 0, 1], [0, 1, 0, 0, 0], [1, 0, 1, 0, 0] ] function dfsManager(map, start, end){ var min = 9999, path = [], unv

  • Python数据结构与算法之图的广度优先与深度优先搜索算法示例

    本文实例讲述了Python数据结构与算法之图的广度优先与深度优先搜索算法.分享给大家供大家参考,具体如下: 根据维基百科的伪代码实现: 广度优先BFS: 使用队列,集合 标记初始结点已被发现,放入队列 每次循环从队列弹出一个结点 将该节点的所有相连结点放入队列,并标记已被发现 通过队列,将迷宫路口所有的门打开,从一个门进去继续打开里面的门,然后返回前一个门处 """ procedure BFS(G,v) is let Q be a queue Q.enqueue(v) lab

  • python深度优先搜索和广度优先搜索

    1. 深度优先搜索介绍 图的深度优先搜索(Depth First Search),和树的先序遍历比较类似. 它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然后依次从它的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和v有路径相通的顶点都被访问到. 若此时尚有其他顶点未被访问到,则另选一个未被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止. 显然,深度优先搜索是一个递归的过程. 2. 广度优先搜索介绍 广度优先搜索算法(Breadt

  • PHP实现深度优先搜索算法(DFS,Depth First Search)详解

    本文实例讲述了PHP实现深度优先搜索算法.分享给大家供大家参考,具体如下: 深度优先搜索的实现原理: 实现代码: <?php class Search_Method { //无向图的数组描述 private $dfs_save; //全局记录数组 private $arr; //控制分支- private $k = 0; public function __construct() { $this->dfs_save = array( array(0,1,1,1,0,0,0,0,0), arra

  • 最短时间学会基于C++实现DFS深度优先搜索

    目录 前言 1.迷宫找出口,区分dfs,bfs: 一.DFS经典放牌可能组合 二.leetcode 员工的重要性 三.leetcode 图像渲染 四.leetcode 被围绕的区域 五.岛屿数量 六. 小练习:岛屿的最大面积 总结 前言 同学们肯定或多或少的听到过别人提起过DFS,BFS,却一直都不太了解是什么,其实两个各为搜索算法,常见使用 深度优先搜索(DFS) 以及 广度优先搜索(BFS) ,今天我们就来讲讲什么是深度优先搜索,深度优先就是撞到了南墙才知道回头,才会往上一层返回. 1.迷宫

  • C++深度优先搜索的实现方法

    本文实例讲述了图的遍历中深度优先搜索的C++实现方法,是一种非常重要的算法,具体实现方法如下: 首先,图的遍历是指从图中的某一个顶点出发,按照某种搜索方法沿着图中的边对图中的所有顶点访问一次且仅访问一次.注意到树是一种特殊的图,所以树的遍历实际上也可以看作是一种特殊的图的遍历.图的遍历主要有两种算法:广度优先搜索(Breadth-First-Search)和深度优先搜索(Depth-First-Search). 一.深度优先搜索(DFS)的算法思想 深度优先搜索算法所遵循的搜索策略是尽可能"深&

  • python实现全排列代码(回溯、深度优先搜索)

    从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列.当m=n时所有的排列情况叫全排列. 公式:全排列数f(n)=n!(定义0!=1) 1 递归实现全排列(回溯思想) 1.1 思想 举个例子,比如你要对a,b,c三个字符进行全排列,那么它的全排列有abc,acb,bac,bca,cba,cab这六种可能就是当指针指向第一个元素a时,它可以是其本身a(即和自己进行交换),还可以和b,c进行交换,故有3种可能,当第一个元素a确定以后,指针移向第二

  • go语言编程学习实现图的广度与深度优先搜索

    目录 图的实现 BFS DFS 图的实现 所谓图就是节点及其连接关系的集合.所以可以通过一个一维数组表示节点,外加一个二维数组表示节点之间的关系. //图的矩阵实现 typedef struct MGRAPH{ nodes int[]; //节点 edges int[][]; //边 }mGraph; 然而对于一些实际问题,其邻接矩阵中可能存在大量的0值,此时可以通过邻接链表来表示稀疏图,其数据结构如图所示 其左侧为图的示意图,右侧为图的邻接链表.红字表示节点序号,链表中为与这个节点相连的节点,

  • C++回溯算法深度优先搜索举例分析

    目录 扑克牌全排列 员工的重要性 图像渲染 被围绕的区域 岛屿数量 电话号码的字母组合 组合总数 活字印书 N皇后 扑克牌全排列 假如有编号为1~ 3的3张扑克牌和编号为1~3的3个盒子,现在需要将3张牌分别放到3个盒子中去,且每个盒子只能放一张牌,一共有多少种不同的放法. 解题思路:假定按照牌面值从小到大依次尝试,即将1号牌放入第一个盒子中.按此顺序继续向后走,放完第三个盒子时,手中的牌也已经用完,再继续往后则到了盒子的尽头.此时一种放法已经完成了,即这条路走到了尽头,需要折返,重新回到上一个

  • 基于Python实现通过微信搜索功能查看谁把你删除了

    场景:查找who删了我,直接copy代码保存到一个python文件who.py,在python环境下运行此文件 代码如下,copy保存到who.py文件在python环境直接运行: #!/usr/bin/env python # coding=utf-8 from __future__ import print_function import os try: from urllib import urlencode, quote_plus except ImportError: from url

随机推荐