一、93 复原IP地址
解决问题过程中,遇到问题:
1 malloc size需要特别注意,可以多考虑一些buff,避免buff不够导致溢出,例如:
void insert(char*s, int pos, char charnode)
{
if(pos > strlen(s))
{
printf("pos is error %d\n", pos);
return;
}
//printf("pos=%d\n", pos);
//这里遇到问题:当时malloc的size不够,导致溢出,所以后面的题目,尽量比memcpy多些size
char* tmp = (char*)malloc(sizeof(char) * (strlen(s) - pos + 10));
int index = 0;
for(int i = pos; i < strlen(s); i++)//保留[pos, size - 1]的字符
{
tmp[index++] = s[i];
}
tmp[index]= '\0';
s[pos] = charnode;
memcpy(s + pos + 1, tmp, strlen(s) - pos + 1);
//printf("char*: %s %d\n", s, strlen(s));
}
2 *returnsize赋初值,如果不满足条件 直接会回NULL;
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
char** result;
int resize;
bool isvalid(char*s, int start, int end)
{
//1 段开头是0不行
if(start > end)
{
return false;
}
if(s[start] == '0' && start != end)
{
return false;
}
int num = 0;
for(int i = start; i <= end; i++)
{
if(s[i] < '0' || s[i] > '9')
{
return false;
}
num = num * 10 + (s[i] - '0');
if(num > 255)
{
return false;
}
}
return true;
}
void insert(char*s, int pos, char charnode)
{
if(pos > strlen(s))
{
printf("pos is error %d\n", pos);
return;
}
//printf("pos=%d\n", pos);
char* tmp = (char*)malloc(sizeof(char) * (strlen(s) - pos + 10));
int index = 0;
for(int i = pos; i < strlen(s); i++)//保留[pos, size - 1]的字符
{
tmp[index++] = s[i];
}
tmp[index]= '\0';
s[pos] = charnode;
memcpy(s + pos + 1, tmp, strlen(s) - pos + 1);
//printf("char*: %s %d\n", s, strlen(s));
}
void erase(char* s, int pos)
{
if(pos > strlen(s))
{
printf("erase pos is error %d\n", pos);
return;
}
//printf("pos %d, %d %s\n",pos, strlen(s), s);
for(int i = pos; i <= strlen(s) - 1; i++)
{
s[i] = s[i + 1];
}
s[strlen(s)] = '\0';
//printf("//%d %s\n",strlen(s), s);
}
void backstacking(char*s, int start, int nodenum)
{
//退出条件:有3个逗号,分4段
if(nodenum == 3)
{
if(isvalid(s, start, strlen(s) -1))//第四段字段合法
{
// result[resize++] = s;
result[resize] = (char*)malloc(sizeof(char*) * strlen(s) + 1);
memcpy(result[resize], s, strlen(s) + 1);//strlen(s)不包括'\0'
resize++;
}
return;
}
for(int i = start; i < strlen(s); i++)
{
if(isvalid(s, start, i))//左闭右闭区间
{
nodenum++;
insert(s, i + 1, '.');//i后面插入
backstacking(s, i + 2, nodenum);//递归的起始位置应该跳过逗号
erase(s, i + 1);
nodenum--;
}
else
break;
}
}
char** restoreIpAddresses(char* s, int* returnSize) {
resize = 0;
result = (char**)calloc(40000, sizeof(char*));
if(strlen(s) < 4 || strlen(s) > 12)
{
*returnSize = 0;
return NULL;
}
char* tmp_s = (char*)calloc(strlen(s) + 100, sizeof(char));
memcpy(tmp_s, s, strlen(s) + 1);//给s扩容
//printf("tmps = %s, len = %d\n", tmp_s, strlen(tmp_s));
backstacking(tmp_s, 0 , 0);
*returnSize = resize;
return result;
}
二、78 子集
区别:组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点!
int* path ;
int** result;
int path_idx;
int resize;
int* recolsize;
// void copy()
// {
// int* tempPath = (int*)malloc(sizeof(int) * path_idx);
// for(int i = 0; i < path_idx; i++) {
// tempPath[i] = path[i];
// }
// result[resize] = tempPath;
// recolsize[resize] = path_idx;
// resize++;
// }
void backstracking(int* nums, int numsSize, int start)
{
result[resize] = (int*)calloc(path_idx + 1, sizeof(int));//(int*)malloc(sizeof(int) * path_idx);
memcpy(result[resize], path, path_idx * sizeof(int));
recolsize[resize] = path_idx;
resize++;
//copy();
if(start >= numsSize)
{
return;
}
for(int i = start; i < numsSize; i++)
{
path[path_idx++] = nums[i];
backstracking(nums, numsSize, i + 1);
path_idx--;
}
}
int** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {
resize = 0;
*returnSize = 0;
path_idx = 0;
recolsize = (int*)malloc(sizeof(int) * 10000);
result = (int**)malloc(sizeof(int) * 10000);
path =(int*)calloc(numsSize, sizeof(int));
*returnColumnSizes = NULL;
if(numsSize == 0)
{
return NULL;
}
backstracking(nums, numsSize, 0);
*returnSize = resize;
*returnColumnSizes = recolsize;
return result;
}
三、子集II
和组合问题结合起来对比着看。注意看代码随想录:“”理解“树层去重”和“树枝去重”!!!
/**
* 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* path ;
int** result;
int path_idx;
int resize;
int* recolsize;
int* used;
void sortArr(int* arr, int size)
{
for(int i = 0; i < size; i++)
{
for(int j = i + 1; j < size; j++)
{
if(arr[i] > arr[j])
{
int tmp = 0;
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
}
void backstracking(int* nums, int numsSize, int start, int* used)
{
result[resize] = (int*)calloc(path_idx + 1, sizeof(int));//(int*)malloc(sizeof(int) * path_idx);
memcpy(result[resize], path, path_idx * sizeof(int));
recolsize[resize] = path_idx;
resize++;
if(start >= numsSize)
{
return;
}
for(int i = start; i < numsSize; i++)
{
if(i > 0 && nums[i] == nums[i -1] && used[i -1] == 0)
{
continue;
}
path[path_idx++] = nums[i];
used[i] = 1;
backstracking(nums, numsSize, i + 1, used);
path_idx--;
used[i] = 0;
}
}
int** subsetsWithDup(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {
resize = 0;
*returnSize = 0;
path_idx = 0;
recolsize = (int*)malloc(sizeof(int) * 10000);
result = (int**)malloc(sizeof(int) * 10000);
path =(int*)calloc(numsSize, sizeof(int));
used = (int*)calloc(numsSize, sizeof(int));
*returnColumnSizes = NULL;
if(numsSize == 0)
{
return NULL;
}
//sort
sortArr(nums, numsSize);
backstracking(nums, numsSize, 0, used);
*returnSize = resize;
*returnColumnSizes = recolsize;
return result;
}