C解法

给定一个二维数组 nums,我们需要计算每个元素到同值元素的最近曼哈顿距离。如果某个元素没有相同值的元素,则返回 -1。
曼哈顿距离:对于两个点 (x1, y1) 和 (x2, y2),曼哈顿距离的计算方式是 abs(x1 - x2) + abs(y1 - y2),即横向和纵向的距离之和。
解题步骤:

第一步:读取输入:
读取矩阵的行数 rows 和列数 cols,然后填充矩阵 nums。
第二步:计算每个元素的最近距离:
遍历矩阵中的每个元素 (i, j)。
对于每个元素,遍历整个矩阵查找所有与该元素值相同且位置不同的元素 (x, y),计算曼哈顿距离并找出最小的距离。
第三步:存储结果并输出:
如果找到了相同值的元素,则将最小距离存储在 result[i][j] 中;如果没有,则存储 -1。
最后输出结果矩阵。
时间复杂度:

时间复杂度:需要遍历矩阵中的每个元素,且对于每个元素,需要再次遍历整个矩阵来查找相同值的元素。最坏情况下,时间复杂度为 O(rows * cols) * O(rows * cols) = O((rows * cols)²)。
空间复杂度:由于需要存储输入矩阵和输出结果矩阵,空间复杂度为 O(rows * cols)。
优化建议:

该解法的时间复杂度较高,对于大矩阵可能会遇到性能瓶颈。可以考虑使用其他方法,例如广度优先搜索(BFS)来优化。

#include 
#include 
#include 

#define MAX_ROWS 100
#define MAX_COLS 100

// 计算整数的绝对值
int abs_val(int a) {
    return a < 0 ? -a : a;
}

int main() {
    int rows, cols;
    int nums[MAX_ROWS][MAX_COLS];  // 输入矩阵
    int result[MAX_ROWS][MAX_COLS]; // 存储结果矩阵

    // Step 1: 读取矩阵的行数和列数
    scanf("%d", &rows);
    scanf("%d", &cols);

    // Step 2: 读取二维数组的每个元素
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            scanf("%d", &nums[i][j]);  // 填充输入矩阵
        }
    }

    // Step 3: 计算每个元素到相同值元素的最小曼哈顿距离
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            int value = nums[i][j];  // 当前元素的值
            int min_distance = INT_MAX;  // 初始化最小距离为最大整数

            // Step 4: 查找与当前值相等的最近元素,遍历整个矩阵
            for (int x = 0; x < rows; x++) {
                for (int y = 0; y < cols; y++) {
                    // 确保不是当前元素自己
                    if ((x != i || y != j) && nums[x][y] == value) {
                        // 计算曼哈顿距离并更新最小距离
                        int distance = abs_val(x - i) + abs_val(y - j);
                        if (distance < min_distance) {
                            min_distance = distance;
                        }
                    }
                }
            }

            // Step 5: 如果没有找到相同值元素,则设置为 -1,否则设置为最小距离
            result[i][j] = (min_distance == INT_MAX) ? -1 : min_distance;
        }
    }

    // Step 6: 输出结果数组,按照指定格式输出
    printf("[");
    for (int i = 0; i < rows; i++) {
        printf("[");
        for (int j = 0; j < cols; j++) {
            printf("%d", result[i][j]);
            if (j < cols - 1) {
                printf(", ");
            }
        }
        printf("]");
        if (i < rows - 1) {
            printf(", ");
        }
    }
    printf("]\n");

    return 0;
}

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

JS解法

具体思路如下:

定义问题:

给定一个整数 n,我们希望通过调整它的二进制表示,找到下一个更大的数字,且新数字的1的个数与 n 相同。
主要步骤:

计算 n 的尾部零和1的数量:
通过右移运算,统计 n 从右侧开始连续的零(c0)和紧接其后的1的数量(c1)。这个过程可以通过连续地右移 n 直到不满足条件。
判断边界情况:
如果 c0 + c1 == 31 或者 c0 + c1 == 0,说明 n 是一个全1的数或全0的数,无法找到更大的数字,直接返回 -1。
找到最小的更大数字:
在 n 的二进制表示中,找到一个合适的位来进行调整,令其变得比 n 大,并且保持相同数量的1。
通过将 n 的某些位置的1变为0,再设置右侧最低的多个0为1来实现这一调整。
关键点:

我们通过 c0 和 c1 确定了需要修改的位置,即确定我们需要操作的比特位。
使用位运算 (| 和 &) 来修改相应的比特

function findNextNumber(n) {
    let temp = n;          // 创建临时变量来操作n
    let c0 = 0, c1 = 0;    // c0表示连续的零的个数,c1表示紧随其后的连续1的个数

    // Step 1: 统计尾部连续的0的个数
    while (((temp & 1) === 0) && (temp !== 0)) {
        c0++;            // 如果当前最低位是0,增加c0
        temp >>= 1;      // 右移一位,继续判断
    }

    // Step 2: 统计尾部连续的1的个数
    while ((temp & 1) === 1) {
        c1++;            // 如果当前最低位是1,增加c1
        temp >>= 1;      // 右移一位,继续判断
    }

    // Step 3: 判断边界情况
    // 如果 c0 + c1 == 31 或者 c0 + c1 == 0,说明无法找到更大的数
    if (c0 + c1 === 31 || c0 + c1 === 0) return -1;

    // Step 4: 计算要修改的位置
    let pos = c0 + c1;      // pos是第一个零的位置,准备变为1
    n |= (1 << pos);         // 在pos位置设置1
    n &= ~((1 << pos) - 1);  // 清除pos后面的所有位
    n |= (1 << (c1 - 1)) - 1; // 在清除后的位置设置c1 - 1个1

    return n;  // 返回修改后的数
}

// 读取输入并处理
const readline = require("readline");
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});

// 读取一行输入
rl.on("line", (line) => {
    const n = parseInt(line.trim());  // 读取输入的整数
    console.log(findNextNumber(n));   // 调用findNextNumber函数并输出结果
});

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

注:本文转载自blog.csdn.net的CodeClimb的文章"https://blog.csdn.net/CodeClimb/article/details/144772422"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!