组合总和系列
Leetcode39 组合总和I
//这个由于组合方案不能重复,我们每次对第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
这个题要求的是数组中的每个元素只能用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
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
//如果求方案种类,递归写法
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[n−1]
那么组成i的集合最后一个数是j时就有
f
[
i
]
=
f
[
i
−
j
]
f[i] = f[i-j]
f[i]=f[i−j]
最后把所有可能的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
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岛屿周长
非递归版本
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岛屿最大面积
//这个题是要求的是图中所有岛屿中有最大面积的那个岛屿
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最大人工岛
这道题用并查集做会更加的高效,对于并查集:
并查集核心思想:
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矩阵
Leetcode241为算数表达式设置优先级
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条边
//和火柴一个做法,几乎能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火柴拼正方形
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子集
/**
* 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(需要去重)
/**
* 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
/**
* 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电话号码组合
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组合总和
/**
* 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;
}
组合总和二
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整数替换
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全排列
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
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优美的排列
这个题用全排列来做,然后中途可以有剪枝
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
Leetcode93
Leetcode64
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二叉树中的最大路径和
/**
* 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分割回文串
/**
* 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
Leetcode576出界路径数
方法一:剪枝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找到树左下角值
/**
* 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括号生成
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所有可能的真二叉树
Leetcode95不同的二叉搜索树II
此题是要输出所有可能的方案,所以用DFS暴搜一下,如果只要求方案数,那么用DP即可
/**
* 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验证二叉搜索树
/**
* 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恢复二叉搜索树
/**
* 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层序遍历
这个题是要返回每一层的节点,然后用一个队列,每次找到这一层的所有节点
/**
* 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二叉树锯齿形遍历
/**
* 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
/**
* 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前序遍历+中序遍历构造二叉树
/**
* 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从中序遍历和后序遍历构造二叉树
/**
* 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
/**
* 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平衡二叉树
/**
* 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
/**
* 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 1240铺瓷砖
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
/**
* 暴搜一下,枚举每个位置即可
*/
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;
}