leetcode-数组-简单-C-第三部分

文章目录

  • 序号832
  • 序号840
  • 序号349
  • 序号350
  • 序号1337
  • 序号1351

序号832

题目:给定一个二进制矩阵 A,我们想先水平翻转图像,然后反转图像并返回结果。
水平翻转图片就是将图片的每一行都进行翻转,即逆序。例如,水平翻转 [1, 1, 0] 的结果是 [0, 1, 1]。
反转图片的意思是图片中的 0 全部被 1 替换, 1 全部被 0 替换。例如,反转 [0, 1, 1] 的结果是 [1, 0, 0]。

解析

  1. 模拟
    对每一行进行逆置,同时反转 0、1
int** flipAndInvertImage(int** A, int ASize, int* AColSize, int* returnSize, int** returnColumnSizes){
    int len = AColSize[0];
    int** ans = (int**)malloc(sizeof(int*) * ASize);
    for (int i = 0; i < ASize; i++)
        ans[i] = (int*)malloc(sizeof(int) * len);
    
    for (int i = 0; i < ASize; i++)
    {
        for (int j = 0; j < (len+1)/2; j++)
        {
            ans[i][j] = 1 - A[i][len-1-j];
            ans[i][len-1-j] = 1 - A[i][j];
        }
    }

    *returnSize = ASize;
    *returnColumnSizes = (int*)malloc(sizeof(int) * ASize);
    for (int i = 0; i < ASize; i++)
        (*returnColumnSizes)[i] = len;
    return ans;
}

序号840

题目:3 x 3 的幻方是一个填充有从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。
给定一个由整数组成的 grid,其中有多少个 3 × 3 的 “幻方” 子矩阵?(每个子矩阵都是连续的)。

解析

  1. 模拟
    遍历每一个 3 × 3 3 \times 3 3×3矩阵,幻方的中间必定是 5
int magic(int* vals) {
    int* hash = (int*)calloc(16, sizeof(int));
    for (int i = 0; i < 9; ++i)
        hash[vals[i]]++;
    for (int i = 1; i <= 9; ++i)  //必须是 1~9
        if (hash[i] != 1)
            return 0;

    free(hash);
    return (vals[0] + vals[1] + vals[2] == 15 &&
            vals[3] + vals[4] + vals[5] == 15 &&
            vals[6] + vals[7] + vals[8] == 15 &&
            vals[0] + vals[3] + vals[6] == 15 &&
            vals[1] + vals[4] + vals[7] == 15 &&
            vals[2] + vals[5] + vals[8] == 15 &&
            vals[0] + vals[4] + vals[8] == 15 &&
            vals[2] + vals[4] + vals[6] == 15);
}

int numMagicSquaresInside(int** grid, int gridSize, int* gridColSize){
    int R = gridSize, C = gridColSize[0];
    int* test = (int*)malloc(sizeof(int) * 9);
    int ans = 0;
    for (int r = 0; r < R-2; ++r)
    {
        for (int c = 0; c < C-2; ++c) {
            if (grid[r+1][c+1] != 5) continue;  // optional skip
            test[0] = grid[r][c]; test[1] = grid[r][c+1]; test[2] = grid[r][c+2];
            test[3] = grid[r+1][c]; test[4] = grid[r+1][c+1]; test[5] = grid[r+1][c+2];
            test[6] = grid[r+2][c]; test[7] = grid[r+2][c+1]; test[8] = grid[r+2][c+2];

            if (magic(test))
                ans++;
        }
    }
    free(test);
    return ans;
}

:源自于题解

序号349

题目:给定两个数组,编写一个函数来计算它们的交集。
说明:
输出结果中的每个元素一定是唯一的。
我们可以不考虑输出结果的顺序。

解析

  1. 暴力解决
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
    int min = nums1Size < nums2Size ? nums1Size : nums2Size;
    int* ans = (int*)malloc(sizeof(int) * min);
    int len = 0;
    int num;

    for (int i = 0; i < nums2Size; i++)
    {
        num = nums2[i];
        for (int j = 0; j < nums1Size; j++)
        {
            if (num == nums1[j])
            {
                int k;
                for (k = 0; k < len; k++)
                {
                    if (num == ans[k])
                        break;
                }
                if (k == len)
                {
                    ans[len] = num;
                    len++;
                }
            }
        }
    }
    *returnSize = len;
    return ans;
}

序号350

题目:给定两个数组,编写一个函数来计算它们的交集。
说明:
输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
我们可以不考虑输出结果的顺序。

解析

  1. 两个数组排序,双指针对着找
    注意排序时,cmp 相减可能越界,用比较返回
int cmp(const void* a, const void* b)
{
    int* pa = (int*)a;
    int* pb = (int*)b;
    if (*pa < *pb)
        return -1;
    else if (*pa > *pb)
        return 1;
    return 0;
}

int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
    qsort(nums1, nums1Size, sizeof(int), cmp);
    qsort(nums2, nums2Size, sizeof(int), cmp);
    int i = 0;
    int j = 0;
    int len = 0;
    int* ans = (int*)malloc(sizeof(int) * nums1Size);

    while (i < nums1Size && j < nums2Size)
    {
        if (nums1[i] < nums2[j])
            i++;
        else if (nums1[i] > nums2[j])
            j++;
        else
        {  
            ans[len] = nums1[i];
            len++;
            i++;
            j++;
        }
    }
    *returnSize = len;
    return ans;
}

序号1337

题目:给你一个大小为 m * n 的方阵 mat,方阵由若干军人和平民组成,分别用 0 和 1 表示。
请你返回方阵中战斗力最弱的 k 行的索引,按从最弱到最强排序。
如果第 i 行的军人数量少于第 j 行,或者两行军人数量相同但 i 小于 j,那么我们认为第 i 行的战斗力比第 j 行弱。
军人 总是 排在一行中的靠前位置,也就是说 1 总是出现在 0 之前。

解析

  1. 模拟
    按列找 0,存入答案数组
    若不如要求长度,从头加入答案数组
int* kWeakestRows(int** mat, int matSize, int* matColSize, int k, int* returnSize){
    int* ans = (int*)malloc(sizeof(int) * k);
    int* hash = (int*)calloc(matSize, sizeof(int));
    int len = 0;
    
    for (int i = 0; i < matColSize[0]; i++)
    {
        for (int j = 0; j < matSize; j++)
        {
            if (mat[j][i] == 0 && hash[j] == 0)
            {
                hash[j] = 1;
                ans[len] = j;
                len++;
                if (len == k)
                {
                    free(hash);
                    *returnSize = k;
                    return ans;
                }
            }
        }
    }
    if (len < k)
    {
        for (int i = 0; i < matSize; i++)
        {
            if (hash[i] == 0)
            {
                ans[len] = i;
                len++;
                if (len == k)
                    break;
            }
        }
    }
    free(hash);
    *returnSize = k;
    return ans;
}

序号1351

题目:给你一个 m * n 的矩阵 grid,矩阵中的元素无论是按行还是按列,都以非递增顺序排列。
请你统计并返回 grid 中 负数 的数目。

解析

  1. 模拟
    因为行列都是非递增的,倒序查找,一旦小于 0,列向下方向都小于 0
    如果不小于 0,就找下一行
int countNegatives(int** grid, int gridSize, int* gridColSize){
    int ans = 0;
    int m = gridSize;
    int n = gridColSize[0];
    int i = 0, temp;

    for (int j = n - 1; j >= 0 && i < m; j--)
    {
        temp = grid[i][j];
        if (temp < 0)
            ans += m - i;
        else
        {
            i++;
            j++;
        }
    }
    return ans;
}

你可能感兴趣的:(C/C++)