Leetcode dfs bfs 递归回溯题目

组合总和系列

Leetcode39 组合总和I

Leetcode dfs bfs 递归回溯题目_第1张图片

//这个由于组合方案不能重复,我们每次对第pos个位置的数,可以进行选0次,选1次...选k次的行为,来计算和
int n;
void dfs(int* candidates,int target,int** res,int *returnSize,int* path,int u,int sum,int** returnColumnSizes,int pos) //pos代表枚举到了哪个位置了
{
    if(sum == target){
        res[*returnSize] = malloc(sizeof(int)*1010);
        for(int i = 0; i < u; i++) res[*returnSize][i] = path[i];
        (*returnColumnSizes)[*returnSize] = u;
        (*returnSize)++;
        return;
    }
    if(pos == n) return;
    for(int k = 0; sum + k * candidates[pos] <= target; k++){
        if(k == 0) dfs(candidates,target,res,returnSize,path,u,sum,returnColumnSizes,pos+1);
        else{
            for(int i = 0; i < k; i++) path[u+i] = candidates[pos];
            dfs(candidates,target,res,returnSize,path,u+k,sum+k*candidates[pos],returnColumnSizes,pos+1); 
        }
    }
}

int** combinationSum(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes){
    n = candidatesSize;
    int** res = malloc(sizeof(int*)*1010);
    int* path = malloc(sizeof(int)*1010);
    (*returnColumnSizes) = malloc(sizeof(int)*1010);
    *returnSize = 0;
    dfs(candidates,target,res,returnSize,path,0,0,returnColumnSizes,0);
    return res;
}

Leetcode40 组合总和II

Leetcode dfs bfs 递归回溯题目_第2张图片
这个题要求的是数组中的每个元素只能用1次,
然后组合不能有重复的,也就是说 1 1 2 3 target = 6
[1,2,3]这个只能出现一次,所以为了去重,需要对原数组进行从小到大的排序,当nums[i] == nums[i-1]但是nums[i-1]没被选用过时,我们不要用nums[i]这样来避免重复

int n;
int cmp(const void *a, const void* b)
{
    return *(int*)a - *(int*)b;
}
bool visit[1010];

void dfs(int* candidates,int n,int** res,int* returnSize,int** returnColumnSizes,int* path,int u,int pos,int sum,int target)
{
    if(sum == target){
        res[*returnSize] = malloc(sizeof(int)*1010);
        for(int i = 0; i < u; i++) res[*returnSize][i] = path[i];
        (*returnColumnSizes)[*returnSize] = u;
        (*returnSize)++;
        return;
    }
    if(sum > target) return;
    if(pos == n) return; //枚举了数组中的所有数但是没找到target的和的直接退出
    visit[pos] = 0;
    dfs(candidates,n,res,returnSize,returnColumnSizes,path,u,pos+1,sum,target);
    if(pos && candidates[pos-1] == candidates[pos] && !visit[pos-1]) return;
    path[u] = candidates[pos];
    visit[pos] = 1;
    dfs(candidates,n,res,returnSize,returnColumnSizes,path,u+1,pos+1,sum+candidates[pos],target);
}

int** combinationSum2(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes){
    n = candidatesSize;
    memset(visit,0,sizeof(visit));
    qsort(candidates,n,sizeof(candidates[0]),cmp);
    int** res = malloc(sizeof(int*)*1010);
    *returnSize = 0;
    (*returnColumnSizes) = malloc(sizeof(int)*1010);
    int* path = malloc(sizeof(int)*1010);
    dfs(candidates,n,res,returnSize,returnColumnSizes,path,0,0,0,target);
    
    return res;
}

Leetcode216 组合总和III

Leetcode dfs bfs 递归回溯题目_第3张图片

void dfs(int** res,int* returnSize,int** returnColumnSizes,int* path,int u,int k,int n,int sum,int len,int pos)
{
    if(len > k) return;
    if(len == k){
        if(sum == n){
            res[*returnSize] = malloc(sizeof(int)*1010);
            for(int i = 0; i < u; i++) res[*returnSize][i] = path[i];
            (*returnColumnSizes)[*returnSize] = u;
            (*returnSize)++;
            return;
        }
    }
    if(pos > 9) return;
    dfs(res,returnSize,returnColumnSizes,path,u,k,n,sum,len,pos+1);
    path[u] = pos;
    dfs(res,returnSize,returnColumnSizes,path,u+1,k,n,sum+pos,len+1,pos+1);
}

int** combinationSum3(int k, int n, int* returnSize, int** returnColumnSizes){
    int** res = malloc(sizeof(int*)*1010);
    *returnSize = 0;
    (*returnColumnSizes) = malloc(sizeof(int)*1010);
    int* path = malloc(sizeof(int)*1010);
    dfs(res,returnSize,returnColumnSizes,path,0,k,n,0,0,1);
    return res;
}

Leetcode 377组合总和IV

Leetcode dfs bfs 递归回溯题目_第4张图片
Leetcode dfs bfs 递归回溯题目_第5张图片

//如果求方案种类,递归写法
int n;
void dfs(int* candidates,int target,int** res,int *returnSize,int* path,int u,int sum,int** returnColumnSizes)
{
    if(sum == target){
        res[*returnSize] = malloc(sizeof(int)*1010);
        for(int i = 0; i < u; i++) res[*returnSize][i] = path[i];
        (*returnColumnSizes)[*returnSize] = u;
        (*returnSize)++;
        return;
    }
    for(int i = 0; i < n; i++){
        if(sum + candidates[i] <= target){
            path[u] = candidates[i];
            dfs(candidates,target,res,returnSize,path,u+1,sum+candidates[i],returnColumnSizes);
        }
    }
}

int combinationSum4(int* nums, int numsSize, int target){
    int* returnSize = malloc(sizeof(int));
    int** returnColumnSizes = malloc(sizeof(int*));
    (*returnColumnSizes) = malloc(sizeof(int)*1010);
    int** res = malloc(sizeof(int*)*1010);
    int* path = malloc(sizeof(int)*1010);
    (*returnColumnSizes) = malloc(sizeof(int)*1010);
    n = numsSize;
    *returnSize = 0;
    dfs(nums,target,res,returnSize,path,0,0,returnColumnSizes);
    return *returnSize;
}

这题只求方案数,可以用动态规划做,
但是这个题还不是完全背包,完全背包会将顺序不同但是组合相同的算作 前一种,比如 1 1 4 和 1 4 1是两种组合,但是完全背包会看作是一种组合

所以我们不要被背包模板所迷惑了,这个题直接考虑
f [ i ] f[i] f[i]表示 i i i的所有划分方案的集合数的最大值(比如 i = 4 i=4 i=4,那么 f [ 4 ] f[4] f[4]就是能够组合成4的所有可能的集合数)
i i i能够由若干数组合而来,比如a+b+c+…+ j = i
由于这个组合是考虑排列序列的,所以我们枚举组合成i的这个组合的最后一个数 j j j,这个 j j j可能是 n u m s [ 0 ] , n u m s [ 1 ] , . . . , n u m s [ n − 1 ] nums[0],nums[1],...,nums[n-1] nums[0],nums[1],...,nums[n1]
那么组成i的集合最后一个数是j时就有 f [ i ] = f [ i − j ] f[i] = f[i-j] f[i]=f[ij]
最后把所有可能的j加起来就是f[i]的结果

int combinationSum4(int* nums, int numsSize, int target){
    int n = numsSize, m = target;
    long long f[m+10]; //f[i]表示i这个值能被划分成的集合数
    memset(f,0,sizeof(f));
    f[0] = 1; //0这个数能被划分的集合数只有1个,那就是空集
    for(int i = 1; i <= m; i++){
        for(int j = 0; j < n; j++)
        {
            if(i>=nums[j]) f[i] = (f[i] + f[i-nums[j]])%INT_MAX;
            // if(i>=nums[j]) printf("%d %d\n",i,i-nums[j]);
        }
    }
    return f[m];
}

Leetcode200

Leetcode dfs bfs 递归回溯题目_第6张图片

int n,m;
int dx[4] = {0,0,1,-1},dy[4] = {1,-1,0,0};

void dfs(char** grid,int x,int y)
{
    if(x < 0 || x >= n || y < 0 || y >= m || grid[x][y] == '0') return;
    grid[x][y] = '0';
    for(int i = 0; i < 4; i++){
        int nx = x + dx[i],ny = y + dy[i];
        dfs(grid,nx,ny);
    }
}

int numIslands(char** grid, int gridSize, int* gridColSize){
    int res = 0;
    n = gridSize,m = gridColSize[0];
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(grid[i][j] == '0') continue;
            res++;
            dfs(grid,i,j);
        }
    }
    return res;
}

Leetcode463岛屿周长

Leetcode dfs bfs 递归回溯题目_第7张图片
Leetcode dfs bfs 递归回溯题目_第8张图片

非递归版本



int islandPerimeter(int** grid, int gridSize, int* gridColSize){
    int res = 0;
    int n = gridSize,m = gridColSize[0];
    int dx[4] = {0,0,1,-1},dy[4] = {1,-1,0,0};
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(grid[i][j] == 0) continue;
            int cnt = 0; //从一个陆地块,看他四周的下一个块是不是越界或者是海洋
            for(int k = 0; k < 4; k++){
                int nx = i + dx[k],ny = j + dy[k];
                if(nx < 0 || nx >= n || ny < 0 || ny >= m || grid[nx][ny] == 0) cnt++;
            }
            res += cnt;
        }
    }
    return res;
}

递归版本

int dx[4] = {1,-1,0,0},dy[4] = {0,0,1,-1};
int dfs(int** grid,int n,int m,int x,int y)
{
    if(x < 0 || x>=n || y < 0 || y >= m || grid[x][y] == 0) return 1;
    if(grid[x][y] == 2) return 0; //如果这个陆地块被访问过,不再加入这个路地块开始遍历的值
    grid[x][y] = 2;
    int ans = 0;
    for(int i = 0; i < 4; i++){
        int nx = x + dx[i],ny = y + dy[i];
        ans += dfs(grid,n,m,nx,ny);
    }
    return ans;
}

int islandPerimeter(int** grid, int gridSize, int* gridColSize){
    int n = gridSize,m = gridColSize[0];
    int res = 0;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(!grid[i][j]) continue;
            res += dfs(grid,n,m,i,j);
        }
    }
    return res;
}

Leetcode695岛屿最大面积

Leetcode dfs bfs 递归回溯题目_第9张图片

//这个题是要求的是图中所有岛屿中有最大面积的那个岛屿
int max(int a,int b)
{
    return a>b?a:b;
}

int dx[4] = {0,0,1,-1},dy[4] = {1,-1,0,0};
int dfs(int** grid,int n,int m,int x,int y)
{
    if(x < 0 || x>=n || y<0 || y>=m || grid[x][y] == 0) return 0;
    int ans = 1;
    grid[x][y] = 0;
    for(int i = 0; i < 4; i++){
        int nx = x + dx[i],ny = y + dy[i];
        ans += dfs(grid,n,m,nx,ny);
    }
    return ans;
}

int maxAreaOfIsland(int** grid, int gridSize, int* gridColSize){
    int res = 0;  //leetcode这里如果把res写成全局变量,第二次调用时,res还是第一次的结果,所以要写到局部变量里
    int n = gridSize,m = gridColSize[0];
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(grid[i][j] == 0){
                printf("yrs\n");
                continue;
            }
            int t = dfs(grid,n,m,i,j);
            res = max(res,t);
        }
    }
    printf("%d",res);
    return res;
}

Leetcode827最大人工岛

Leetcode dfs bfs 递归回溯题目_第10张图片
这道题用并查集做会更加的高效,对于并查集:

并查集核心思想:
int p[N]; //定义个parent数字,代表i号点的父亲是几号点
然后最开始所有 p[i] = i代表自己是一个集合
//定义核心函数int find(int x)
int find(int x)
{
    if(x!=p[x]) p[x] = find(p[x]);
    return p[x];
}
/***
基本思想:
首先将所有不联通的岛屿,构成一个个并查集,并且记录下每一个岛屿的面积
然后枚举每一个grid[i][j] = 0的点,然后看把这个点变为1后其上下左右是否有不同的与这个单独的快联通的并查集
然后把这几个并查集的面积加起来再加1就是新的联通块面积了
***/
int n,m;
int* p;    //定义i号节点的父节点
int* area;  //连通块面积
int dx[4] = {1,-1,0,0},dy[4] = {0,0,1,-1};

int max(int a,int b)
{
    return a>b?a:b;
}

int get(int a,int b)
{
    return a*m + b; //二维数组下标变一维的方法就是  行坐标*列数 + 纵坐标
}

int find(int x)    // 并查集核心函数,查找x号节点的父节点
{
    if(p[x] != x) p[x] = find(p[x]);
    return p[x];  
}

int largestIsland(int** grid, int gridSize, int* gridColSize){
    n = gridSize,m = gridColSize[0];
    int res = 0;
    p = malloc(sizeof(int)*1000000);
    area = malloc(sizeof(int)*1000010);

    for(int i = 0; i < n * m; i++){  //并查集初始化
        p[i] = i;
        area[i] = 1;
    }
    
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(grid[i][j]){
                int a = get(i,j); //(i,j)所属的并查集编号
                for(int k = 0; k < 4; k++){
                    int nx = i + dx[k],ny = j + dy[k];
                    if(nx>=0 && nx<n && ny>=0 && ny<m && grid[nx][ny]){
                        int b = get(nx,ny);
                        if(find(a) != find(b)){
                            area[find(b)] += area[find(a)];
                            p[find(a)] = find(b);
                        }
                    }
                }
                res = max(res,area[find(a)]);
            }
        }
    }
    for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++){
            if(!grid[i][j]){
                int hash[1000010];
                memset(hash,0,sizeof(hash));
                int s = 1;
                for(int k = 0; k < 4; k++){
                    int nx = i + dx[k],ny = j + dy[k];
                    if(nx>=0 && nx<n && ny>=0 && ny<m && grid[nx][ny]){
                        int a = get(nx,ny);
                        if(!hash[find(a)]){
                            hash[find(a)] = area[find(a)];
                            s += area[find(a)];
                        }
                    }
                }
                res = max(res,s);
            }
        }
    }
    return res;
}

Leetcode542 01矩阵

Leetcode dfs bfs 递归回溯题目_第11张图片

Leetcode241为算数表达式设置优先级

Leetcode dfs bfs 递归回溯题目_第12张图片

int* dfs(char* s,int l,int r,int *returnSize)
{
    if(l > r){
        int* res = malloc(sizeof(int)*10);
        *returnSize = 0;
        return res;
    }
    int *res = malloc(sizeof(int)*10100);
    *returnSize = 0;
    for(int i = l ; i <= r; i++){
        if(s[i]>='0' && s[i]<='9') continue; //是数字的时候直接过
        //此时s[i]= + - * 中的一种
        int* leftsize = malloc(sizeof(int));
        int* rightsize = malloc(sizeof(int));
        int* left = dfs(s,l,i-1,leftsize);
        int* right = dfs(s,i+1,r,rightsize);
        for(int j = 0; j < *leftsize; j++){
            for(int k = 0; k < *rightsize; k++){
                int t = 1;
                if(s[i] == '+') t = left[j] + right[k];
                else if(s[i] == '-') t = left[j] - right[k];
                else if(s[i] == '*') t = left[j] * right[k];
                res[*returnSize] = t;
                (*returnSize)++;
            }
        }
    }
    if(*returnSize == 0){//说明这一段的字符只有数字没有运算符
        int ans = 0;
        for(int i = l; i <= r; i++) ans = ans * 10 + s[i] - '0';
        res[*returnSize] = ans;
        (*returnSize)++;
    }
    return res;
}
int* diffWaysToCompute(char * expression, int* returnSize){
    int n = strlen(expression);
    return dfs(expression,0,n-1,returnSize);
}

Leetcode698划分为k个等和子集

这题和那个拼火柴的基本是一个题,拼火柴是把数组拼成4条边,这个是把数组拼成k条边
Leetcode dfs bfs 递归回溯题目_第13张图片

//和火柴一个做法,几乎能AC所以的
int cmp(const void* a,const void* b)
{
    int* aa = (int*)a;
    int* bb = (int*)b;
    if(*aa < *bb) return 1;
    return -1;
}

bool dfs(int* board,int* nums,int n,int u,int len,int k)
{
    bool flag = true;
    for(int i = 0; i < k; i++){
        if(board[i] != len){
            flag = false;
            break;
        }
    }
    if(flag) return true; //如果k段都已经设置为了长度len,那么能找到方案
    if(u >= n) return false; //找遍数组还没找到答案
    for(int i = 0; i < k; i++){
        if(board[i] + nums[u] > len) continue;
        board[i] += nums[u];
        if(dfs(board,nums,n,u+1,len,k)) return true;
        board[i] -= nums[u];
    }
    return false;
}

bool canPartitionKSubsets(int* nums, int n, int k){
    int sum = 0;
    for(int i = 0; i < n; i++) sum += nums[i];
    if(sum % k) return false; //总和不是k的倍数,说明不可能划分为k段
    int len = sum / k; //若能够划分为k段,则每段的长度为 sum / k
    qsort(nums,n,sizeof(nums[0]),cmp);
    if(nums[0] > len) return false;
    int* board = malloc(sizeof(int)*(k+10)); //board[i]记录每一段已经放了多长
    for(int i = 0; i < k; i++) board[i] = 0;
    return dfs(board,nums,n,0,len,k);
}

Leetcode473火柴拼正方形

Leetcode dfs bfs 递归回溯题目_第14张图片
Leetcode dfs bfs 递归回溯题目_第15张图片

int cmp(const void* a,const void* b)
{
    int* aa = (int*)a;
    int* bb = (int*)b;
    if(*aa < *bb) return  1;
    return -1;
}

bool dfs(int* board,int len,int* nums,int n,int u) //u代表枚举到nums中的哪一个位置了
{
    if(board[0] == len && board[1] == len && board[2] == len && board[3] == len) return true; 
    if(u == n) return false; //如果遍历没了还没找到答案,一定是错的(因为来到这个if就是上面那个成功条件没满足)
    for(int i = 0; i < 4; i++){//把当前这个火柴分别放到4个边上
        if(board[i] + nums[u] > len) continue;
        board[i] += nums[u];
        if(dfs(board,len,nums,n,u+1)) return true;
        board[i] -= nums[u];
    }
    return false;
}

bool makesquare(int* matchsticks, int matchsticksSize){
    int n = matchsticksSize;
    if(n < 3) return false; //小于3根不可能拼成正方形
    int sum = 0;
    for(int i = 0; i < n; i++) sum += matchsticks[i];
    if(sum%4!=0) return false; //如果长度总和不是4的倍数,那么直接退出
    int len = sum / 4; //正方形每个边的长度
    qsort(matchsticks,n,sizeof(matchsticks[0]),cmp); //从大到小排序,先枚举大的
    for(int i = 0; i < n; i++){
        if(matchsticks[i] > len) return false; //如果最长的边超过了可能拼成的正方形边长,直接退出
    }
    int* board = malloc(sizeof(int)*8); //board记录正方形4个边的每个边已经枚举了多长了
    for(int i = 0; i < 4; i++) board[i] = 0;
    return dfs(board,len,matchsticks,n,0);
}

Leetcode78子集

Leetcode dfs bfs 递归回溯题目_第16张图片

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int* visit;
int** res;


void dfs(int* returnSize,int* nums,int n,int** returnColumnSizes,int u)
{
    if(u == n){
        int cnt = 0;
        res[*returnSize] = malloc(sizeof(int)*100010);
        for(int i = 0; i < n; i++){
            if(visit[i]){
                res[*returnSize][cnt++] = nums[i];
            }
        }
        int t = *returnSize;
        (*returnColumnSizes)[t] = cnt;  //这里这么写会缓冲区溢出,但是我没明白怎么就溢出了
        (*returnSize)++;
         return;
    }
    visit[u] = 1;
    dfs(returnSize,nums,n,returnColumnSizes,u+1);
    visit[u] = 0;
    dfs(returnSize,nums,n,returnColumnSizes,u+1);
    
}

int** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    *returnColumnSizes = malloc(sizeof(int)*(1<<numsSize));
    visit = malloc(sizeof(int)*(numsSize+10));
    res = malloc(sizeof(int*)*(1000000));
    *returnSize = 0;
    dfs(returnSize,nums,numsSize,returnColumnSizes,0);
    return res;
}

leetcode90 子集2(需要去重)

Leetcode dfs bfs 递归回溯题目_第17张图片

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int *visit;
int *path;
int cnt;
int **res;
int cmp(const void *a,const void *b)
{
    return *(int*)a - *(int*)b;
}

void dfs(int **res,int* nums,int n,int *returnSize,int** returnColumnSizes,int u)
{
    if(u == n){
        res[*returnSize] = malloc(sizeof(int)*10000);
        int cnt = 0;
        for(int i = 0; i < n; i++){
            if(visit[i]){
                res[*returnSize][cnt++] = nums[i];
            }
        }
        (*returnColumnSizes)[*returnSize] = cnt;
        (*returnSize)++;
        return;
    }
    //去重时,不执行不选nums[i]的,然后看nums[i-1] == nums[i]且nums[i-1]是不是还没选过
    visit[u] = 0;
    path[cnt++] = nums[u];
    dfs(res,nums,n,returnSize,returnColumnSizes,u+1);
    if(u && nums[u-1] == nums[u] && !visit[u-1]) return;
    visit[u] = 1;
    cnt--;
    dfs(res,nums,n,returnSize,returnColumnSizes,u+1);
}

int** subsetsWithDup(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    qsort(nums,numsSize,sizeof(int),cmp);
    *returnSize = 0;
    *returnColumnSizes = malloc(sizeof(int)*10000);
    visit = malloc(sizeof(int)*10000);
    path = malloc(sizeof(int)*10000);
    res = malloc(sizeof(int*)*10000);
    dfs(res,nums,numsSize,returnSize,returnColumnSizes,0);
    return res;
}

Leetcode77

Leetcode dfs bfs 递归回溯题目_第18张图片

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** res;
int visit[30];

void dfs(int n,int k,int u,int pos,int *returnSize,int** returnColumnSizes)
{
    if(n - pos + 1 + u < k) return;
    if(u == k){
        res[*returnSize] = malloc(sizeof(int)*30);
        int cnt = 0;
        for(int i = 1; i <= n; i++){
            if(visit[i]){
                res[*returnSize][cnt++] = i;
            }
        }
        (*returnColumnSizes)[*returnSize] = cnt; //必须写(*returnColumnSizes)[*returnSize] 带括号!!
        (*returnSize)++;
        return;
    }
    visit[pos] = 1;  //这里要先弄选这个数的方案,不能把visit[pos]=0放这里,要不会有问题
    dfs(n,k,u+1,pos+1,returnSize,returnColumnSizes);
    visit[pos] = 0;
    dfs(n,k,u,pos+1,returnSize,returnColumnSizes);
}

int** combine(int n, int k, int* returnSize, int** returnColumnSizes){
    memset(visit,0,sizeof(visit));
    res = malloc(sizeof(int)*300000000);
    *returnSize = 0;
    *returnColumnSizes = malloc(sizeof(int)*3000000);
    dfs(n,k,0,1,returnSize,returnColumnSizes);
    return res;
}

Leetcode17电话号码组合

Leetcode dfs bfs 递归回溯题目_第19张图片

char str[10][10] = {"\0","\0","abc\0","def\0","ghi\0","jkl\0","mno\0","pqrs\0","tuv\0","wxyz\0"};
char** res;
char path[100000];
int cnt = 0;

void dfs(char* digits,int* returnSize,int n,int u)
{
    if(u == n){
        printf("%d\n",cnt);
        res[*returnSize] = malloc(sizeof(char)*(n+10));
        for(int i = 0; i < cnt; i++){
            res[*returnSize][i] = path[i];
        }
        res[*returnSize][strlen(path)] = '\0';
        (*returnSize)++;
        return;
    }
    int num = digits[u] - '0'; 
    int len = strlen(str[num]);
    for(int i = 0; i < len; i++){
        path[cnt++] = str[digits[u] - '0'][i];
        dfs(digits,returnSize,n,u+1);
        cnt--; 
    }
    return;
}

char ** letterCombinations(char * digits, int* returnSize){
    if(!strlen(digits)){
        *returnSize = 0;
        return res;
    }
    *returnSize = 0;  //这个初始化必须有
    res = malloc(sizeof(char*)*1000000);
    memset(path,'\0',sizeof(path));
    dfs(digits,returnSize,strlen(digits),0);

    return res;
}

Leetcode39组合总和

Leetcode dfs bfs 递归回溯题目_第20张图片

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int **res;
int* path;
int cnt = 0;
int visit[500];
void dfs(int* candidates,int n,int target,int* returnSize,int** returnColumnSizes,int sum,int pos)
{
    if(pos == n){//pos==n表示遍历完一遍这个数组,每个位置有选和不选
        if(sum == target){
            res[*returnSize] = malloc(sizeof(int)*500);
            for(int i = 0; i < cnt; i++){
                res[*returnSize][i] = path[i];
            }
            (*returnColumnSizes)[*returnSize] = cnt;
            (*returnSize)++;
        }
        return;
    } 
    for(int i = 0; candidates[pos] * i <= target;i++){ //i代表这个数被使用几次
        if(i){
            visit[candidates[pos]]++;
            path[cnt++] = candidates[pos];
            sum += candidates[pos];
        }
        dfs(candidates,n,target,returnSize,returnColumnSizes,sum,pos+1);
    }
    cnt -= visit[candidates[pos]];
    visit[candidates[pos]] = 0;
}

int** combinationSum(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes){
    if(candidatesSize == 0){
        *returnSize = 0;
        return res;
    }
    memset(visit,0,sizeof(visit));
    res = malloc(sizeof(int*)*500);
    path = malloc(sizeof(int)*500);
    (*returnColumnSizes) = malloc(sizeof(int)*500);
    *returnSize = 0;
    dfs(candidates,candidatesSize,target,returnSize,returnColumnSizes,0,0);
    return res;
}

组合总和二

Leetcode dfs bfs 递归回溯题目_第21张图片

int** res;
int* path;
int cnt;
int visit[110];
int cmp(const void* a,const void *b)
{
    return *(int*)a - *(int*)b;
}

void dfs(int* candidates,int n,int target,int *returnSize,int** returnColumnSizes,int sum,int pos)
{
    if(pos == n){
        if(sum == target){
            res[*returnSize] = malloc(sizeof(int)*1100);
            for(int i = 0; i <cnt; i++) res[*returnSize][i] = path[i];
            (*returnColumnSizes)[*returnSize] = cnt;
            (*returnSize)++;
        }
        return;
    }
    visit[pos] = 0;
    dfs(candidates,n,target,returnSize,returnColumnSizes,sum,pos+1);
    if(pos && candidates[pos-1]==candidates[pos] && !visit[pos-1]) return;
    visit[pos] = 1;
    path[cnt++] = candidates[pos];
    dfs(candidates,n,target,returnSize,returnColumnSizes,sum+candidates[pos],pos+1);
    cnt--;
    visit[pos] = 0;
    

}

int** combinationSum2(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes){
    qsort(candidates,candidatesSize,sizeof(int),cmp);
    res = malloc(sizeof(int*)*1100);
    path = malloc(sizeof(int)*1100);
    *returnColumnSizes = malloc(sizeof(int)*1100);
    memset(visit,0,sizeof(visit));
    *returnSize = 0;
    if(!candidatesSize) return res;
    dfs(candidates,candidatesSize,target,returnSize,returnColumnSizes,0,0);
    return res;
}

Leetcode397整数替换

Leetcode dfs bfs 递归回溯题目_第22张图片

int dfs(long long n)
{
    if(n==1) return 0;
    int res = 0x3f3f3f3f;
    if(n%2==0) res = fmin(res,dfs(n/2));
    if(n%2==1) res = fmin(res,fmin(dfs(n+1),dfs(n-1)));
    return res+1;
}

int integerReplacement(int n){
    int res = dfs(n);
    return res;
}

Leetcode 216

在这里插入图片描述

int* nums;
int** res;
int* path;
int cnt = 0;
int visit[10010];
void dfs(int* nums,int n,int k,int target,int pos,int sum,int* returnSize,int** returnColumnSizes)
{
    if(pos == n){
        if(sum == target && cnt == k){
            res[*returnSize] = malloc(sizeof(int)*10010);
            for(int i = 0; i < cnt; i++) res[*returnSize][i] = path[i];
            (*returnColumnSizes)[*returnSize] = cnt;
            (*returnSize)++;
        }
        return;
    }
    visit[pos] = 1;
    path[cnt++] = nums[pos];
    dfs(nums,n,k,target,pos+1,sum+nums[pos],returnSize,returnColumnSizes);
    visit[pos] = 0;
    cnt--;
    dfs(nums,n,k,target,pos+1,sum,returnSize,returnColumnSizes);
}

int** combinationSum3(int k, int n, int* returnSize, int** returnColumnSizes){
    res = malloc(sizeof(int*)*10010);
    path = malloc(sizeof(int)*10010);
    memset(visit,0,sizeof(visit));
    nums = malloc(sizeof(int)*10010);
    *returnColumnSizes = malloc(sizeof(int)*10010);
    for(int i = 0; i < 9; i++) nums[i] = i + 1;
    int len = 9;
    *returnSize = 0;
    dfs(nums,len,k,n,0,0,returnSize,returnColumnSizes);
    return res;
}

46全排列

Leetcode dfs bfs 递归回溯题目_第23张图片

int **res;
int* path;
int cnt = 0;
int visit[2000];

void dfs(int* nums,int n, int* returnSize,int** returnColumnSizes,int u)
{
    if(u == n){
        res[*returnSize] = malloc(sizeof(int)*2000);
        for(int i = 0; i < cnt; i++) res[*returnSize][i] = path[i];
        (*returnColumnSizes)[*returnSize] = cnt;
        (*returnSize)++;
        return;
    }
    for(int i = 0; i < n; i++){
        if(!visit[i]){
            visit[i] = 1;
            path[cnt++] = nums[i];
            dfs(nums,n,returnSize,returnColumnSizes,u+1);
            cnt--;
            visit[i] = 0;
        }
    }
}

int** permute(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    res = malloc(sizeof(int*)*2000);
    path = malloc(sizeof(int)*2000);
    memset(visit,0,sizeof(visit));
    *returnSize = 0;
    if(!numsSize) return res;
    *returnColumnSizes = malloc(sizeof(int)*2000);
    dfs(nums,numsSize,returnSize,returnColumnSizes,0);
    return res;
}

Leetcode47

Leetcode dfs bfs 递归回溯题目_第24张图片

int** res;
int* path;
int cnt = 0;
int  visit[2000];
int cmp(const void* a,const void* b)
{
    return *(int*)a - *(int*)b;
}

void dfs(int* nums,int n,int *returnSize,int** returnColumnSizes,int u)
{
    if(u == n){
        res[*returnSize] = malloc(sizeof(int)*2000);
        for(int i = 0; i < cnt; i++) res[*returnSize][i] = path[i];
        (*returnColumnSizes)[*returnSize] = cnt;
        (*returnSize)++;
        return;
    }
    for(int i = 0; i < n; i++){
        if(visit[i]) continue;
        if(i && nums[i] == nums[i-1] && !visit[i-1]) continue;
        visit[i] = 1;
        path[cnt++] = nums[i];
        dfs(nums,n,returnSize,returnColumnSizes,u+1);
        cnt--;
        visit[i] = 0;
    }
}

int** permuteUnique(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    qsort(nums,numsSize,sizeof(int),cmp);
    res = malloc(sizeof(int*)*2000);
    path = malloc(sizeof(int)*2000);
    memset(visit,0,sizeof(visit));
    *returnSize = 0;
    if(!numsSize) return res;
    (*returnColumnSizes) = malloc(sizeof(int)*2000);
    dfs(nums,numsSize,returnSize,returnColumnSizes,0);
    return res;
}

Leetcode526优美的排列

Leetcode dfs bfs 递归回溯题目_第25张图片
这个题用全排列来做,然后中途可以有剪枝

bool visit[20];
int res;
int n;
void dfs(int u)
{
    if(u == (n+1)){
        res++;
        return;
    }
    for(int i = 1; i <= n; i++){
        if(!visit[i]){
            if(i%u == 0 || u%i==0){
                visit[i] = true;
                dfs(u+1);
                visit[i] = false;
            }
        }
    }
}

int countArrangement(int _n){
    res = 0;
    n = _n;
    memset(visit,0,sizeof(visit));
    for(int i = 1; i <= n; i++){
        visit[i] = true;
        dfs(2);
        visit[i] = false;
    }
    return res;
}

Leetcode131

Leetcode dfs bfs 递归回溯题目_第26张图片

Leetcode93

Leetcode dfs bfs 递归回溯题目_第27张图片

Leetcode64

Leetcode dfs bfs 递归回溯题目_第28张图片

static int res;
int dx[2] = {1,0},dy[2] = {0,1};
int max(int a,int b)
{
    return a>b?a:b;
}
int min(int a,int b)
{
    return a<b?a:b;
}
void dfs(int** grid,int n,int m,int x,int y,int path)
{
    if(x >= n || y >= m) return;
    if(x == n - 1 && y == m - 1){
        res = min(res,path+grid[x][y]);
        return;
    }
    path += grid[x][y];
    for(int i = 0; i < 2; i++){
        int nx = x + dx[i],ny = y + dy[i];
        dfs(grid,n,m,nx,ny,path);
    }

}

int minPathSum(int** grid, int gridSize, int* gridColSize){
    res = 1000000;
    int n = gridSize, m = gridColSize[0];
    dfs(grid,n,m,0,0,0);
    return res;
}

Leetcode124二叉树中的最大路径和

Leetcode dfs bfs 递归回溯题目_第29张图片
在这里插入图片描述

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
static int res;
int dfs(struct TreeNode* root)  //返回以这个点开始到所有其子孙叶子节点中,最长的路径
{
    if(root == NULL){
        return 0;
    }
    int ans = root -> val;
    int left = fmax(dfs(root->left),0);
    int right = fmax(dfs(root->right),0);
    res = fmax(res,ans+left+right); //寻找  /\ 这样的路径
    return ans + fmax(left,right);
}

int maxPathSum(struct TreeNode* root){
    res = -1100;
    dfs(root);
    return res;
}

Leetcode131分割回文串

Leetcode dfs bfs 递归回溯题目_第30张图片
Leetcode dfs bfs 递归回溯题目_第31张图片

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */

bool ifstr(char * s, int i, int j)//判断是否为回文串
{
    while(i <= j)
    {
        if(s[i] != s[j])
            return false;
        i++;
        j--;
    }
    return true;
}


void dfs(char * s, char *** ans, int * returnSize, int ** returnColumnSizes, int len, char ** path, int path_i,int index)//递归回溯枚举子串
{
   
    if(index >= len)//切割到最后了,保存有效组合
    {
        ans[(*returnSize)] = (char**)malloc(sizeof(char *) * path_i);
        for(int i = 0; i < path_i; i++)
        {
            ans[(*returnSize)][i] = (char *)malloc(sizeof(char) * (len+1));
            strcpy(ans[(*returnSize)][i], path[i]);
        }
        (*returnColumnSizes)[(*returnSize)++] = path_i;
        return;
    }
    for(int i = index; i < len; i++)
    {
        if(ifstr(s, index, i) == false) continue;//剪枝,当前不满足切割条件,就没必要在枚举了
        strncpy(path[path_i], s+index, i-index+1);//满足切割条件,保存子串
        path[path_i][i-index+1] = '\0';
        dfs(s, ans, returnSize, returnColumnSizes, len, path, path_i+1, i+1);//递归重复之前动作
        //其中path_i+1, i+1 都是回溯,因为是实参传个形参,形参不会改变实参的值,所以实际没有变,相等于 i++,再i--
    }
    return;
}

char *** partition(char * s, int* returnSize, int** returnColumnSizes){
    char *** ans = (char ***)malloc(sizeof(int **) * 50000);
    (*returnColumnSizes) = (int *)malloc(sizeof(int) * 50000);
    int len = strlen(s);
    char ** path = (char **)malloc(sizeof(char *) * len);
    for(int i = 0; i < len; i++)
    {
        path[i] = (char *)malloc(sizeof(char) * (len+1));
    }
    *returnSize = 0;//初始化变量
    dfs(s, ans, returnSize, returnColumnSizes,len, path, 0, 0);
    return ans;
}

Leetcode241

Leetcode dfs bfs 递归回溯题目_第32张图片
Leetcode dfs bfs 递归回溯题目_第33张图片

Leetcode576出界路径数

Leetcode dfs bfs 递归回溯题目_第34张图片
题目详解

方法一:剪枝DFS

static int res;
int dx[4] = {0,0,1,-1},dy[4] = {1,-1,0,0};
void dfs(int m,int n,int u,int v,int k)
{
    if(u < 0 || u >= m || v < 0 || v >= n){
        res++;
        return;
    }
    if(k == 0) return;
    //剪枝:如果小球怎样都不能移出,直接退出
    if(u-k>=0 && v-k>=0 && u+k<m && v+k<n) return;
    for(int i = 0; i < 4; i++){
        int nx = u + dx[i], ny = v + dy[i];
        dfs(m,n,nx,ny,k-1);
    }
}

int findPaths(int m, int n, int maxMove, int startRow, int startColumn){
    res = 0;
    dfs(m,n,startRow,startColumn,maxMove);
    return res;
}

AC:记忆化搜索DFS

#define mod (long long)(1e9+7)
int dx[4] = {0,0,1,-1},dy[4] = {1,-1,0,0};
int f[60][60][60]; //f[i][j][k]表示从(i,j)这个点移动k次,最终出界的路径数

int dfs(int m,int n,int u,int v,int k)
{
    if(u < 0 || u >= m || v < 0 || v >= n){
        return 1;
    }
    if(k == 0) return 0;
    //剪枝:如果小球怎样都不能移出,直接退出
    if(u-k>=0 && v-k>=0 && u+k<m && v+k<n) return 0;
    //剪枝:如果这个点之前得到了走k步出界的结果,直接返回之前的结果,不在搜索了
    if(f[u][v][k] != -1) return f[u][v][k];
    int ans = 0;
    for(int i = 0; i < 4; i++){
        int nx = u + dx[i], ny = v + dy[i];
        ans = (ans + dfs(m,n,nx,ny,k-1))%mod;  //这种取余的一定是写成a = (a+c)%mod 一定不是 a += c%mod
    }
    f[u][v][k] = ans;
    return ans;
}

int findPaths(int m, int n, int maxMove, int startRow, int startColumn){
    memset(f,0,sizeof(f));
    for(int i  = 0; i < m; i++){
        for(int j = 0; j <n; j++){
            for(int k = 0; k <= maxMove; k++) f[i][j][k] = -1; //-1表示(i,j)这个点移动k次出界的情况还没被访问过
        }
    }
    int res  =  dfs(m,n,startRow,startColumn,maxMove);
    return res;
}

Leetcode513找到树左下角值

Leetcode dfs bfs 递归回溯题目_第35张图片

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
static int res;
static int max_level;
void dfs(struct TreeNode* root,int u){
    if(!root) return;
    if(!root->left && !root->right && u > max_level){
        max_level = u;
        res = root->val;
        return;
    }
    dfs(root->left,u+1);
    dfs(root->right,u+1);
}

int findBottomLeftValue(struct TreeNode* root){
    res = 0,max_level = -1;
    dfs(root,0);
    return res;
}

Leetcode22括号生成

Leetcode dfs bfs 递归回溯题目_第36张图片

char* path;
int cnt;
void dfs(char** res,int* returnSize,int n,int left,int right)
{
    if(left == n && right == n){
        res[*returnSize] = malloc(sizeof(char)*5000);
        for(int i = 0; i < cnt; i++) res[*returnSize][i] = path[i];
        res[*returnSize][cnt] = '\0';
        (*returnSize)++;
        return;
    }
    if(left < n){
        path[cnt++] = '(';
        dfs(res,returnSize,n,left+1,right);
        cnt--;
    }
    if(right < left){
        path[cnt++] = ')';
        dfs(res,returnSize,n,left,right+1);
        cnt--;
    }
}

char ** generateParenthesis(int n, int* returnSize){
    char** res = malloc(sizeof(char*)*5000);
    path = malloc(sizeof(char)*5000);
    cnt = 0;
    *returnSize = 0;
    dfs(res,returnSize,n,0,0);
    return res;
}

Leetcode894所有可能的真二叉树

Leetcode dfs bfs 递归回溯题目_第37张图片

Leetcode95不同的二叉搜索树II

此题是要输出所有可能的方案,所以用DFS暴搜一下,如果只要求方案数,那么用DP即可
Leetcode dfs bfs 递归回溯题目_第38张图片

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */


/**
 * 给每个节点一个编号从1~n
 */
struct TreeNode** dfs(int l,int r,int* returnSize)
{
    if(l > r){
        //空树的集合
        struct TreeNode** res = malloc(sizeof(struct TreeNode*));
        *returnSize = 1;
        res[0] = NULL;
        return res;
    }
    struct TreeNode** res = malloc(sizeof(struct TreeNode*)*10000);
    for(int i = l; i <= r; i++){
        int* leftsize = malloc(sizeof(int));
        int* rightsize = malloc(sizeof(int));
        *leftsize = 0,*rightsize = 0;
        struct TreeNode** left = dfs(l,i-1,leftsize);
        struct TreeNode** right = dfs(i+1,r,rightsize);
        for(int j = 0; j < *leftsize; j++){
            for(int k = 0; k < *rightsize; k++){
                struct TreeNode* root = malloc(sizeof(struct TreeNode));
                root->val = i;
                root->left = left[j];
                root->right = right[k];
                res[*returnSize] = root;
                (*returnSize)++;
            }
        }
    }
    return res;
}

struct TreeNode** generateTrees(int n, int* returnSize){
    *returnSize = 0;
    return dfs(1,n,returnSize);
}

Leetcode98验证二叉搜索树

Leetcode dfs bfs 递归回溯题目_第39张图片

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
 //输出中序遍历,然后和排序后的数组比较即可
long long* res;
long long* ans;
int cmp(const void* a,const void *b)
{
    long long* aa = (long long*)a;  //用long long等别写*(long long*)a - *(long long*)b因为cmp是个int,这样可能溢出
    long long* bb = (long long*)b;
    if(*aa > *bb) return 1;
    return -1;
}
void dfs(struct TreeNode* root,int* size)
{
    if(!root) return;
    dfs(root->left,size);
    res[*size] = root->val;
    (*size)++;
    dfs(root->right,size);

}

bool isValidBST(struct TreeNode* root){
    int size = 0;
    res = malloc(sizeof(long long)*10000);
    ans = malloc(sizeof(long long)*10000);
    dfs(root,&size);
    for(int i = 0; i < size; i++) ans[i] = res[i];
    qsort(ans,size,sizeof(ans[0]),cmp);
    bool flag = true;
    for(int i = 0; i < size; i++){
        if(i > 0 && ans[i] == ans[i-1]){
            flag = false;
            break;
        }
        if(res[i] != ans[i]){
            flag = false;
            break;
        }
    }
    for(int i = 0; i < size; i++) printf("%lld ",ans[i]);
    printf("\n");
    for(int i = 0; i < size; i++) printf("%lld ",res[i]);
    return flag;
}

Leetcode99恢复二叉搜索树

Leetcode dfs bfs 递归回溯题目_第40张图片

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
long long* res;
long long* ans;
int num[10];
int cmp(const void* a,const void* b)
{
    long long *aa = (long long*)a;
    long long *bb = (long long*)b;
    if(*aa > *bb) return 1;
    return -1;
}

void dfs(struct TreeNode* root,int* n)
{
    if(!root) return;
    dfs(root->left,n);
    res[*n] = root->val;
    (*n)++;
    dfs(root->right,n);
}

void dfs2(struct TreeNode* root)
{
    if(!root) return;
    if(root->val == num[0]) root->val = num[1];
    else if(root->val == num[1]) root->val = num[0];
    dfs2(root->left);
    dfs2(root->right);
}

void recoverTree(struct TreeNode* root){
    res = malloc(sizeof(long long)*1010);
    ans = malloc(sizeof(long long)*1010);
    memset(num,0,sizeof(num));
    int n = 0;
    dfs(root,&n);
    
    for(int i = 0; i < n; i++){
        ans[i] = res[i];
    }
    qsort(ans,n,sizeof(ans[0]),cmp);
    for(int i = 0; i < n; i++){
        if(ans[i] != res[i]){
            num[0] = ans[i];
            num[1] = res[i];
            break;
        }
    }
    dfs2(root);
}

Leetcode102层序遍历

Leetcode dfs bfs 递归回溯题目_第41张图片
这个题是要返回每一层的节点,然后用一个队列,每次找到这一层的所有节点

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */


/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes){
    int** res = malloc(sizeof(int*)*1000);
    *returnColumnSizes = malloc(sizeof(int)*1000);
    *returnSize = 0;
    if(!root) return res;
    struct TreeNode* queue[10100];  
    int front = 0,tail = -1;
    queue[++tail] = root;
    while(front<=tail){
        int start = front,end = tail;
        res[*returnSize] = malloc(sizeof(int)*10100);
        (*returnColumnSizes)[*returnSize] = end - start + 1;
        for(int i = 0; i <= end - start; i++){
            res[*returnSize][i] = queue[i+start]->val;
            if(queue[i+start]->left != NULL) queue[++tail] = queue[start+i]->left;
            if(queue[i+start]->right) queue[++tail] = queue[start+i]->right;
        }
        (*returnSize)++;
        front = end + 1;
    }
    return res;
}

Leetcode103二叉树锯齿形遍历

Leetcode dfs bfs 递归回溯题目_第42张图片

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */


/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** zigzagLevelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes){
    int** res = malloc(sizeof(int*)*1010);
    (*returnColumnSizes) = malloc(sizeof(int)*1010);
    *returnSize = 0;
    if(!root) return res;
    struct TreeNode* queue[1010];
    int ff = 0,tt = -1, level = 0; //偶数层正序输出,奇数层,倒序输出
    queue[++tt] = root;
    while(ff <= tt)
    {
        int start = ff, end = tt;
        res[*returnSize] = malloc(sizeof(int)*1010);
        (*returnColumnSizes)[*returnSize] = end - start + 1;
        for(int i = start; i <= end; i++){
            if(queue[i]->left) queue[++tt] = queue[i]->left;
            if(queue[i]->right) queue[++tt] = queue[i]->right;
        }
        if(level%2 == 0){
            for(int i = 0; i < end - start + 1; i++){
                res[*returnSize][i] = queue[start + i]->val;
            }
        }
        else if(level%2){
            for(int i = 0; i <= end - start; i++){
                res[*returnSize][i] = queue[end-i]->val;
            }
        }
        (*returnSize)++;
        level++;
        ff = end + 1;
    }
    return res;
}

Leetcode107二叉树层序遍历II

Leetcode dfs bfs 递归回溯题目_第43张图片

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */


/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** levelOrderBottom(struct TreeNode* root, int* returnSize, int** returnColumnSizes){
    int** res = malloc(sizeof(int*)*1010);
    *returnSize = 0;
    (*returnColumnSizes) = malloc(sizeof(int)*1010);
    if(!root) return res;
    struct TreeNode* queue[10100];
    int front = 0, tail = -1;
    queue[++tail] = root;
    while(front <= tail){
        int start = front, end = tail;
        res[*returnSize] = malloc(sizeof(int)*1010);
        (*returnColumnSizes)[*returnSize] = end - start + 1;
        for(int i = 0; i <= end-start; i++){
            res[*returnSize][i] = queue[start+i]->val;
            if(queue[start+i]->left) queue[++tail] = queue[start+i]->left;
            if(queue[start+i]->right) queue[++tail] = queue[start+i]->right;
        }
        (*returnSize)++;
        front = end + 1;
    }
    int tmp[10100];
    memset(tmp,0,sizeof(tmp));
    int n = *returnSize;
    for(int i = 0; i < n; i++) tmp[i] = (*returnColumnSizes)[i];
    int l = 0, r = n-1;
    while(l < r)
    {
        int t = (*returnColumnSizes)[l];
        (*returnColumnSizes)[l] = (*returnColumnSizes)[r];
        (*returnColumnSizes)[r] = t;
        l++,r--;
    }
    int** ans = malloc(sizeof(int*)*1010);
    for(int i = 0; i < n; i++){
        ans[i] = malloc(sizeof(int)*1010);
        for(int j = 0; j < tmp[n-1-i]; j++){
            ans[i][j] = res[n-1-i][j];
        }
    }
    return ans;

}


Leetcode105前序遍历+中序遍历构造二叉树

Leetcode dfs bfs 递归回溯题目_第44张图片

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int hash[10010];
struct TreeNode* build(int* preorder,int prel,int prer,int* inorder,int inl,int inr)
{
    if(prel > prer){
        return NULL;
    }
    struct TreeNode* root = malloc(sizeof(struct TreeNode));
    root->val = preorder[prel];
    int k = hash[root->val+3010] - inl;
    root->left = build(preorder,prel+1,k+prel,inorder,inl,inl+k-1);
    root->right = build(preorder,prer-(inr-inl-k-1),prer,inorder,inl+k+1,inr);
   return root;
}

struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize){
    if(!preorderSize) return NULL;
    memset(hash,0,sizeof(hash));
    struct TreeNode* root = malloc(sizeof(struct TreeNode));
    for(int i = 0; i < inorderSize; i++) hash[inorder[i]+3010] = i; //记录这个数在中序遍历中的位置,便于查找
    root->val = preorder[0];
    int k = hash[preorder[0]+3010];
    root->left = build(preorder,1,k,inorder,0,k-1);
    root->right = build(preorder,k+1,preorderSize-1,inorder,k+1,inorderSize-1);
    return root;
}

Leetcode106从中序遍历和后序遍历构造二叉树

Leetcode dfs bfs 递归回溯题目_第45张图片

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int hash[6020];
struct TreeNode* build(int* inorder,int inl,int inr,int* postorder,int postl,int postr)
{
    if(inl > inr) return NULL;
    struct TreeNode* root = malloc(sizeof(struct TreeNode));
    root->val = postorder[postr];
    int k = hash[root->val+3000] - inl;
    root->left = build(inorder,inl,inl+k-1,postorder,postl,postl+k-1);
    root->right = build(inorder,inl+k+1,inr,postorder,postl+k,postr-1);
    return root;
}

struct TreeNode* buildTree(int* inorder, int inorderSize, int* postorder, int postorderSize){
    memset(hash,0,sizeof(hash));
    int n = inorderSize;
    for(int i = 0; i < n; i++) hash[inorder[i]+3000] = i;
    struct TreeNode* root = build(inorder,0,n-1,postorder,0,n-1);
    return root;
}

Leetcode108有序数组转化为平衡BST

Leetcode dfs bfs 递归回溯题目_第46张图片
Leetcode dfs bfs 递归回溯题目_第47张图片

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
struct TreeNode* build(int* nums,int l,int r)
{
    if(l > r) return NULL;
    struct TreeNode* root = malloc(sizeof(struct TreeNode));
    int mid = (l+r)/2;
    root->val = nums[mid];
    root->left = build(nums,l,mid-1);
    root->right = build(nums,mid+1,r);
    return root; 
}

struct TreeNode* sortedArrayToBST(int* nums, int numsSize){
    return build(nums,0,numsSize-1);
}

Leetcode110平衡二叉树

Leetcode dfs bfs 递归回溯题目_第48张图片

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int find_height(struct TreeNode* root)
{
    if(!root) return 0;
    int left = find_height(root->left);
    int right = find_height(root->right);
    return fmax(left,right) + 1;
}

bool dfs(struct TreeNode* root)
{
    if(!root) return true;
    int left = find_height(root->left);
    int right = find_height(root->right);
    if(abs(left-right) >= 2) return false;
    return dfs(root->left) && dfs(root->right);
}

bool isBalanced(struct TreeNode* root){
    return dfs(root);
}

Leetcode112路径总和

在这里插入图片描述

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
bool dfs(struct TreeNode* root,int target,int sum)
{
    if(root->left == NULL && root->right == NULL){
        if((sum+root->val)==target) return true;
        return false;
    }
    bool left = false, right = false;
    if(root->left) left = dfs(root->left,target,sum+root->val);
    if(root->right) right = dfs(root->right,target,sum+root->val);
    return left || right;
}

bool hasPathSum(struct TreeNode* root, int targetSum){
    if(!root) return false;
    return dfs(root,targetSum,0);
}

Leetcode113路径总和II

Leetcode dfs bfs 递归回溯题目_第49张图片

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int** res;
int* path;
void dfs(struct TreeNode* root, int target, int sum,int* returnSize,int** returnColumnSizes,int cnt)
{
    if(!root->left && !root->right)
    {
        if(target == (sum+root->val))
        {
            res[*returnSize] = malloc(sizeof(int)*1010);
            path[cnt++] = root->val;
            for(int i = 0; i <cnt; i++) res[*returnSize][i] = path[i];
            (*returnColumnSizes)[*returnSize] = cnt;
            (*returnSize)++;
        }
        return;
    }
    path[cnt++] = root->val;
    if(root->left) dfs(root->left,target,sum+root->val,returnSize,returnColumnSizes,cnt);
    if(root->right) dfs(root->right,target,sum+root->val,returnSize,returnColumnSizes,cnt);
}

int** pathSum(struct TreeNode* root, int target, int* returnSize, int** returnColumnSizes){
    res = malloc(sizeof(int*)*1010);
    path = malloc(sizeof(int)*1010);
    int cnt = 0;
    (*returnColumnSizes) = malloc(sizeof(int)*1010);
    *returnSize = 0;
    if(!root) return res;
    dfs(root,target,0,returnSize,returnColumnSizes,cnt);
    return res;
}

Leetcode337打家劫舍III

Leetcode dfs bfs 递归回溯题目_第50张图片
Leetcode dfs bfs 递归回溯题目_第51张图片

Leetcode 1240铺瓷砖

Leetcode dfs bfs 递归回溯题目_第52张图片

bool visit[200][200];
int res;
bool check(int x,int y,int len)
{
    for(int i = x; i < x + len; i++){
        for(int j = y; j < y + len; j++){
            if(visit[i][j]) return false;
        }
    }
    return true;
}

void fill(int x,int y, int len,bool flag)
{
    for(int i = x; i < x + len; i++){
        for(int j = y; j < y + len; j++){
            visit[i][j] = flag;
        }
    }
}

void dfs(int n,int m,int x,int y,int cnt) //cnt表示铺到(x,y)这个点之前已经铺了多少个正方形了
{
    if(cnt >= res) return; //如果已经比铺满用的正方形块更多,那么直接退出即可
    if(y == m){
        x = x + 1;
        y = 0;
    }
    if(x == n){
        res = cnt;
    }
    else{
        if(visit[x][y]) dfs(n,m,x,y+1,cnt);
        else{
            for (int len = fmin(n - x, m - y); len; len -- ) {
                    if (check(x, y, len)) {
                        fill(x, y, len, true);
                        dfs(n,m, x, y + 1, cnt + 1);
                        fill(x, y, len, false);
                    }
                }
        }
    }
}


int tilingRectangle(int n, int m){
    //先行后列,枚举每个(i,j)作为正方形的左上角,然后枚举长度len
    memset(visit,0,sizeof(visit));
    res = 410; //res 全局变量,表示铺满整个正方形需要的最小的正方形块数目
    dfs(n,m,0,0,0);
    return res;
}

Leetcode967

Leetcode dfs bfs 递归回溯题目_第53张图片

/**
 *  暴搜一下,枚举每个位置即可
 */
int* res;
void dfs(int n, int k, int u,int path, int *returnSize)
{
    if(u == n){
        res[*returnSize] = path;
        (*returnSize)++;
        return;
    }
    if(path%10-k >= 0) dfs(n,k,u+1,path*10+path%10-k,returnSize);
    if(k==0) return;
    if(path%10+k <= 9) dfs(n,k,u+1,path*10+path%10+k,returnSize);
}


int* numsSameConsecDiff(int n, int k, int* returnSize){
    res = malloc(sizeof(int)*10010);
    *returnSize = 0;
    for(int i = 1; i <= 9; i++){
        dfs(n,k,1,i,returnSize);
    }
    return res;
} 

你可能感兴趣的:(算法,深度优先,leetcode,宽度优先)