力扣(526.401)补7.22

526.优美的排列

递归回溯这东西不画图,很难想。

这个回溯也是要了我老命了,对我来说还有点难理解,另外,照答案写结果最后一直显示数组越界,怎么找都找不到错误,明明和答案一模一样,最后才发现match分配空间的(int*)被我搞成(int),烦死了。

那个全局变量num如果直接赋值,会报错,在主函数赋值没问题,这点我不懂。

backtrack是循环填充第index个位置。并把被填的数设为true。到第index+1时,说明产生一种可能,num+1。真的很绕蛙。

int **match;

int *matchColSize;

int *vis;

int num;

 

void backtrack(int index, int n) {

    if (index == n + 1) {

        num++;

        return;

    }

    for (int i = 0; i < matchColSize[index]; i++) {

        int x = match[index][i];

        if (!vis[x]) {

            vis[x] = true;

            backtrack(index + 1, n);

            vis[x] = false;

这里我也不明白为啥数组元素可设为T,F,这里T/F相当于0/1。

        }

    }

}

 

int countArrangement(int n) {

    vis = malloc(sizeof(int) * (n + 1));

    match = malloc(sizeof(int *) * (n + 1));

    matchColSize = malloc(sizeof(int) * (n + 1));

    memset(matchColSize, 0, sizeof(int) * (n + 1));

    memset(vis, 0, sizeof(int) * (n + 1));

    num = 0;

    for (int i = 1; i <= n; i++) {

        match[i] = malloc(sizeof(int) * (n));

        for (int j = 1; j <= n; j++) {

            if (i % j == 0 || j % i == 0) {

                match[i][matchColSize[i]++] = j;

            }

        }

    }

    backtrack(1, n);

    return num;

}

401.二进制手表

本来用回溯想好思路,结果一直报错。最终没办法,看答案结果用枚举法,真的头疼。心都要化成灰了。

表的形式要用sprintf函数,而__builtin_popcount()用于计算参数的二进制(一个 32 位无符号整数)有多少个位为1。踏马👻能想到呢 ,呵呵😒,我真的服了,cnmd。

而且这里%02d和%2d不一样。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值