240509.LeetCode——1828.统计一个圆中点的数目

题目描述

给你一个数组 points ,其中 points[i] = [xi, yi] ,表示第 i 个点在二维平面上的坐标。多个点可能会有 相同 的坐标。

同时给你一个数组 queries ,其中 queries[j] = [xj, yj, rj] ,表示一个圆心在 (xj, yj) 且半径为 rj 的圆。

对于每一个查询 queries[j] ,计算在第 j 个圆  点的数目。如果一个点在圆的 边界上 ,我们同样认为它在圆  。

请你返回一个数组 answer ,其中 answer[j]是第 j 个查询的答案。

EX1.

160994f79a06463c8d415e50aa28fd25.jpg  

输入:points = [[1,3],[3,3],[5,3],[2,2]], queries = [[2,3,1],[4,3,1],[1,1,2]]
输出:[3,2,2]
解释:所有的点和圆如上图所示。
queries[0] 是绿色的圆,queries[1] 是红色的圆,queries[2] 是蓝色的圆。

EX2.

29e0d995b81c4c209b0c7627db4358e2.jpg

输入:points = [[1,1],[2,2],[3,3],[4,4],[5,5]], queries = [[1,2,2],[2,2,2],[4,3,2],[4,3,3]]
输出:[2,3,2,4]
解释:所有的点和圆如上图所示。
queries[0] 是绿色的圆,queries[1] 是红色的圆,queries[2] 是蓝色的圆,queries[3] 是紫色的圆。

提示

  • 1 <= points.length <= 500
  • points[i].length == 2
  • 0 <= x​​​​​​i, y​​​​​​i <= 500
  • 1 <= queries.length <= 500
  • queries[j].length == 3
  • 0 <= xj, yj <= 500
  • 1 <= rj <= 500
  • 所有的坐标都是整数。

代码实现

C语言

/**
* Note: The returned array must be malloced, assume caller calls free().
*/

//返回的矩阵是动态分配定义的,假设调用后会被free掉

int distance(int x1,int y1,int x2,int y2)//返回两个二维平面的点之间距离的平方
{
    int distance;
    distance = ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    return distance;
}

int* countPoints(int** points, int pointsSize, int* pointsColSize, int** queries, int queriesSize, int* queriesColSize, int* returnSize)//Point的ColSize为2,queriers的ColSize为3,下面代码将直接用数字表示,实际上真正的代码规范应该全都用变量名来调用
{
    int i;//两个循环变量定义
    int j;
    int *answer=(int*)malloc(sizeof(int)*queriesSize);//根据给出的圆的数目多少来动态分配定义返回的数组
    memset(answer,0,sizeof(int)*queriesSize);//昨天刚刚学到的用于初始化动态数组的memset函数

    int dis;//定义新变量,追求可读性,将圆心和点的距离平方记录下来
    for(i=0;i<queriesSize;i++)//第一层循环遍历每个圆
    {
        for(j=0;j<pointsSize;j++)//第二层循环对每个圆遍历每一个点
        {
            dis=distance(queries[i][0],queries[i][1],points[j][0],points[j][1]);//自定义函数调用
            if(dis<=queries[i][2]*queries[i][2])
            {
                answer[i]++;//若点在该圆内,计数器+1
            }
        }
    }
    *returnSize=queriesSize;//这一步有点重要,之前编译一直错误或者输出错误就是因为漏了这一句,但是具体作用是什么呢?
    return answer;
}

思路:

第一次读题,没读懂。第二次配合图像读读懂了,第一个思路就是两个循环,第一个循环遍历所有圆,第二个循环对每个单独圆遍历每个点。遇到了几个问题,第一趟代码写完,编译没过。第一个错是说前面的distance计算不能用squr函数,尽管我引入了<math.h>,后面换个思想,发现也不用那么精细,就用平方值就足够,而且还能避免开平方出现浮点数导致精度损失(看题解才了解到的,当时没想那么多)。第二个问题,输出的数组没有大小,后面发现是漏了:

*returnSize=queriesSize;//当然也是看了题解才懂的

这句话的原理是什么,我没弄懂,喂给AI之后,得到的回复是:

    关于您提到的疑问:

- `*returnSize=queriesSize;` 这行代码的作用是设置输出参数`returnSize`的值。在C语言中,函数可以通过输出参数(通常是指针)来返回额外的信息。在这个函数中,`returnSize`指针被用来告知调用者返回数组`answer`的大小,这样调用者就知道需要为`answer`数组分配多少空间,并且在使用完毕后知道何时可以释放这个数组。

这时候才知道设计的牛逼之处!!!使用指针(数组)作为函数参数,避免传值导致另创副本,然后得到的returnSize就是answer的Size,这时候输出才会有长度,也便于随后调用者的free操作!但是还有一个小小疑问:

为什么没有这行代码,数组的数组就没有长度了?

继续喂给AI,再次学到新东西:

//

在C语言中,数组本身不包含其长度的信息。数组的长度必须由程序员在编写代码时明确跟踪和传递,因为数组在传递给函数时,其长度信息不会自动包含在内。这是C语言的一个特性,与数组的传递和表示方式有关。

当您在C语言中定义一个数组,如下所示:

```c
int array[10];
```

编译器会为这个数组分配一个连续的内存空间,但数组本身不会存储其长度。当你将数组作为参数传递给函数时,实际上传递的是指向数组首元素的指针,而数组的长度信息不会随之传递。

例如,当你调用一个函数:

```c
void someFunction(int arr[]) {
    // 在这里,编译器不知道arr的长度
}
```

`someFunction`接收到的只是一个指针,它不知道这个数组的长度。因此,如果你需要在函数内部使用数组的长度,你必须以参数的形式显式传递它。这就是为什么在处理数组的函数中,你经常会看到额外的参数用来表示数组的长度。

在您提供的代码示例中,`countPoints`函数返回一个指向整数数组的指针,这个数组包含了每个查询的结果。由于数组长度信息不会随指针自动传递,所以需要`returnSize`参数来显式传递这个信息。调用者需要知道这个长度,以便正确地处理返回的数组,例如遍历它或最终释放其内存。

如果没有`returnSize`参数,调用者将无法知道返回数组的长度,这将导致无法正确地使用该数组,也没有办法正确地释放分配的内存,从而可能导致内存泄漏或其他潜在的错误。因此,`returnSize`参数是必要的,以确保数组可以被正确和安全地使用。

//

原来输入输出数组的时候,并不会并带传入数组的长度,需要另外设置参数来表示数组长度...怪不得很多题目都是数组和长度分两个参数传入参数!然后回到题目本身,answer的长度很显然就是queris的长度,所以用queriesSize就没什么疑问了,但是前面的代码不能出现*returnSize,因为这时候还是一个为止值,不会报错,但是输出不对。还要说的一点是*returnSize表示的是returnSize指向的地址的值,表示return的长度(有点绕),大概意思就是,当做指针来用,要加上*号,表示地址指向的地方的值(大概是个int?)。

总结

       本来想今天早上写的,结果今天早上又忍不住刷手机,结果中午的时候推到下午,下午的时候又突发奇想想去English Corner...感觉还蛮好玩的,一共发言了三次嘿嘿,不知道听感怎么样,反正讲感还挺好的,而且还交到了朋友。btw,真的高水平,感觉十个人里五六个人雅思都可以7.5+(当然不包括我)。老师态度也很和善(好像是中亚的?),也很耐心,很温柔嘿嘿。然后就没写力扣...包括原本计划要写的大统赛论文也没写,然后现在力扣写到这已经晚上9:03。

      还是回到这道题本身吧,这种解法在题解区貌似被称为暴力求解法?然后好像到这大家都开始关注内存占用量和运行时间了,然后看到题解区有用所谓二分法查找的,但我看不懂,之前貌似听过科普,但真正coding实现还是不熟悉...明天看看,下次找机会补一下...这道题应该是暴力解和二分法的效率差不多,可能是数据量比较小吧,换作更高维度就未必了...

      不管怎样,还是坚持下来了,然后平板今天也买了,心里没有什么顾虑的了,先趁着三分钟热度还在,卷他几天再说。加油!

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值