代码随想录训练营20day-回溯3

一、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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值