稀土掘金刷题-打点计数器

88 阅读2分钟

问题描述

小明想发明一台打点计数器,这个计数器有这样的一个功能:

  • 它可以接收一个递增的数据范围(形如[3, 9]),其中第一个数字代表起始,第二个数字代表结束

  • 这个数据范围中包含几个数字,打点计数器就会打几个点

  • 在传入的多组数据范围中,如果出现了范围的重复,机器则不会重复打点

你可以帮助小明算一算,在不同的情况下,计数器会打出几个点么?

输入格式

一个二维数组

输出格式

一个整数,表达在输入是这个数组的情况下,计数器打出的点数

解题思路: 首先,我们接收到的是一个二维数组,数组中的每个元素又是一个表示数据范围的一维数组,形如 [起始数字, 结束数字] 。

对于每一个数据范围,我们需要计算出这个范围内数字的个数。可以通过用结束数字减去起始数字再加 1 来得到,比如范围 [3, 9] ,数字个数就是 9 - 3 + 1 = 7 个。

接下来,我们把每一个数据范围的数字个数累加起来。

但是要注意,如果出现了重复的范围,我们不能重复计算点数。为了避免重复计算,我们可以使用一个集合来存储已经计算过的范围。在计算新的范围时,先检查这个集合中是否已经存在相同的范围,如果不存在,就将数字个数累加到总点数中,并把这个范围加入集合;如果存在,就跳过不进行累加。

最后,得出的总点数就是计数器打出的点数。

测试用例:

`int main() { int testArray1[][2] = {{1, 4}, {7, 10}, {3, 5}}; int testArray2[][2] = {{1, 2}, {6, 10}, {11, 15}};

printf("%d\n", solution((int**)testArray1, 3, 2) == 7);
printf("%d\n", solution((int**)testArray2, 3, 2) == 9);

return 0;

}`

(题目描述有些问题,数据范围应该不包括左边或者右边的边界)

算法描述:

遍历二维数组给出的数字范围,将出现过的数字利用一个新的布尔类型数组进行标记,统计一共有多少个被标记过的数字

`​ int solution(int** inputArray, int rows, int cols) {

bool nums[2000000000]={false};//定义一个bool类型的数组,用来标记是否遍历过
int count=0;
for(int i=0;i<rows;i++)
{
    int start=inputArray[i][0];
    int end=inputArray[i][1];
    for(;start<end;start++)//应该是<而不是<=,因为不包含一侧的边界
    {
        if(nums[1000000000+end]==false)//判断是否遍历过
        {
           nums[1000000000+end]=true;
           count++; 
        }
    }
}
return count;
// Please write your code here*/

}

​`