56. 两数之和

本文介绍了一个经典的算法问题——两数之和。给定一个整数数组和目标值,找出数组中和为目标值的两个数,并返回它们的下标。文章提供了具体的解决方案和示例代码。

给一个整数数组,找到两个数使得他们的和等于一个给定的数 target

你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标。注意这里下标的范围是 0 到 n-1

 注意事项

你可以假设只有一组答案。

样例

给出 numbers = [2, 7, 11, 15], target = 9, 返回 [0, 1].

挑战 

Either of the following solutions are acceptable:

  • O(n) Space, O(nlogn) Time

  • O(n) Space, O(n) Time

vector<int> twoSum(vector<int> &numbers, int target) {
        // write your code here
        vector<int> a;
        for(int i=0;i<numbers.size();i++){
            for(int j=i+1;j<numbers.size();j++){
                if(numbers[i]+numbers[j]==target){
                    a.push_back(i);
                    a.push_back(j);
                    return a;
                }
            }
        }
        return a;
    }

<think> 我们有一个地址块129.250.0.0/16,需要分配给16个地点,每个地点有250台计算机(因为4000台/16个地点=250台/地点)。我们需要为每个地点分配一个子网,并计算每个子网中IP地址的最小值和最大值。 步骤: 1. 确定每个地点所需的地址块大小。 - 每个地点需要250个主机地址。由于每个子网中,网络地址和广播地址不可用,所以我们需要满足:2^h - 2 >= 250,其中h是主机位的位数。 - 计算:当h=8时,2^8 - 2 = 254 >= 250,满足要求。因此,每个子网需要至少8位主机位,即子网掩码为/24(因为32-8=24)。 2. 原始地址块是/16,即前16位是网络前缀,后16位可以用于子网划分。现在我们需要划分16个子网,每个子网是/24。 - 16个子网需要4位(因为2^4=16)子网位。因此,我们可以将原始地址块的后16位中的前4位作为子网位,剩下的12位作为主机位。但是,根据上一步,我们只需要8位主机位,所以实际上我们只需要从后16位中拿出8位作为主机位,而剩下的8位(16-8=8)可以用于子网划分。但是,我们只需要16个子网,所以只需要4位子网位(2^4=16),因此我们可以使用4位子网位和8位主机位,这样每个子网就是/20+4? 不对,重新考虑。 实际上,原始网络前缀是16位,现在每个子网需要24位前缀,即我们需要从原来的主机部分(16位)中拿出8位作为子网位(因为24-16=8),这样就有2^8=256个子网,而我们需要16个,所以足够。 因此,我们可以将地址块划分为多个/24的子网,然后分配其中的16个。 3. 分配方案: - 起始地址:129.250.0.0/16 - 第一个子网:129.250.0.0/24(但通常避免使用全0子网,所以我们可以从129.250.1.0/24开始?或者按照标准,全0子网也是可用的,但为了避免传统问题,这里我们按照RFC950,可以使用全0子网,但为了清晰,也可以跳过0。不过,题目没有特别要求,我们可以使用全0子网。但注意,在CIDR中,全0子网是可用的。这里我们按照连续分配即可。 但是,为了简单起见,我们通常从0开始。所以: - 地点1:129.250.0.0/24 - 地点2:129.250.1.0/24 - 这样分配?不对,因为129.250.0.0/24和129.250.1.0/24是连续的,但是注意,129.250.0.0/24的地址范围是129.250.0.0到129.250.0.255,而129.250.1.0/24的地址范围是129.250.1.0到129.250.1.255。但是这样分配,我们实际上使用了子网号0和1,但是注意,在第三个八位字节中,0和1是连续的。 然而,我们只需要16个子网,所以我们可以分配从0到15的第三个八位字节。 因此,分配如下: - 地点1:129.250.0.0/24 - 地点2:129.250.1.0/24 - ... - 地点16:129.250.15.0/24 为什么是15?因为0到15一共16个数。 4. 每个子网的IP地址最小值和最大值: 以地点1(129.250.0.0/24)为例: - 网络地址:129.250.0.0 - 最小IP地址(即第一个可用地址):129.250.0.1(但题目要求的是整个地址块中的最小和最大IP地址,包括网络地址和广播地址?注意,题目要求“每个地址块中IP地址的最小值和最大值”,这里应该包括网络地址和广播地址,因为它们是地址块中的地址。 - 广播地址:129.250.0.255 - 所以最小IP地址是129.250.0.0,最大IP地址是129.250.0.255。 同样,地点2:129.250.1.0/24,最小IP地址是129.250.1.0,最大是129.250.1.255。 但注意,地点16:129.250.15.0/24,最小IP地址是129.250.15.0,最大是129.250.15.255。 5. 验证:每个子网有256个地址(从0到255),其中可用的主机地址有254个(去掉网络地址和广播地址),满足250台计算机的要求。 因此,分配方案如下: | 地点 | 地址块 | 最小IP地址 | 最大IP地址 | |------|----------------|--------------|---------------| | 1 | 129.250.0.0/24 | 129.250.0.0 | 129.250.0.255 | | 2 | 129.250.1.0/24 | 129.250.1.0 | 129.250.1.255 | | 3 | 129.250.2.0/24 | 129.250.2.0 | 129.250.2.255 | | 4 | 129.250.3.0/24 | 129.250.3.0 | 129.250.3.255 | | 5 | 129.250.4.0/24 | 129.250.4.0 | 129.250.4.255 | | 6 | 129.250.5.0/24 | 129.250.5.0 | 129.250.5.255 | | 7 | 129.250.6.0/24 | 129.250.6.0 | 129.250.6.255 | | 8 | 129.250.7.0/24 | 129.250.7.0 | 129.250.7.255 | | 9 | 129.250.8.0/24 | 129.250.8.0 | 129.250.8.255 | | 10 | 129.250.9.0/24 | 129.250.9.0 | 129.250.9.255 | | 11 | 129.250.10.0/24| 129.250.10.0 | 129.250.10.255| | 12 | 129.250.11.0/24| 129.250.11.0 | 129.250.11.255| | 13 | 129.250.12.0/24| 129.250.12.0 | 129.250.12.255| | 14 | 129.250.13.0/24| 129.250.13.0 | 129.250.13.255| | 15 | 129.250.14.0/24| 129.250.14.0 | 129.250.14.255| | 16 | 129.250.15.0/24| 129.250.15.0 | 129.250.15.255| 注意:这里我们使用了第三个八位字节从0到15,共16个子网。 但是,这里有一个问题:129.250.0.0/24和原始地址块129.250.0.0/16的地址是重叠的?实际上,129.250.0.0/16包含129.250.0.0/24,所以这是正常的子网划分。 另外,我们也可以选择不使用0子网,而从1开始到16。但是,根据RFC 1878,在CIDR环境中,全0和全1子网都是可用的。所以这里使用0子网没有问题。 如果不想使用0子网,那么可以分配从1到16,即: 地点1:129.250.1.0/24 地点2:129.250.2.0/24 ... 地点16:129.250.16.0/24 这样也是连续的16个子网。两种方式都可以。这里我们按照第一种方式(0到15)来分配,因为这样可以节省地址(0到15比1到16少用一个16,但0到15是16个,1到16也是16个,所以地址使用量相同)。但注意,0到15:0,1,...,15(16个数),1到16:1,2,...,16(也是16个数)。所以两种方式都可以。 这里我们采用0到15,因为这是从0开始的最自然的分配。 因此,按照上述表格。 </think>### 对4个/24地址块的最大可能聚合分析 给定4个连续的/24地址块: 1. 212.56.132.0/24 2. 212.56.133.0/24 3. 212.56.134.0/24 4. 212.56.135.0/24 #### 步骤1:转换为二进制形式 | 地址块 | 二进制表示(第三字节) | 说明 | |----------------|-----------------------|------| | 212.56.132.0/24 | 10000100 | 第三字节二进制表示 | | 212.56.133.0/24 | 10000101 | 第三字节二进制表示 | | 212.56.134.0/24 | 10000110 | 第三字节二进制表示 | | 212.56.135.0/24 | 10000111 | 第三字节二进制表示 | #### 步骤2:寻找公共前缀位 - 前16位(212.56)相同(固定前缀) - 第三字节二进制分析: ``` 132: 10000100 133: 10000101 134: 10000110 135: 10000111 ``` - 公共前缀位:前22位(16+6) - 前6位相同:100001(对应十进制132-135的共同前缀) - 最后2位不同:00/01/10/11 #### 步骤3:计算聚合地址块 - 聚合后前缀长度:22位(212.56.132.0/22) - 地址范围: - 最小地址:212.56.132.0(二进制:212.56.10000100.00000000) - 最大地址:212.56.135.255(二进制:212.56.10000111.11111111) #### 验证聚合正确性 - 聚合块212.56.132.0/22包含: - 212.56.132.0/24(132=10000100) - 212.56.133.0/24(133=10000101) - 212.56.134.0/24(134=10000110) - 212.56.135.0/24(135=10000111) - 排除其他地址块(如212.56.136.0/24等),因为第三字节10001000(136)的前6位不同 #### 结论 最大可能的聚合地址块是:**212.56.132.0/22** - 最小IP地址:212.56.132.0 - 最大IP地址:212.56.135.255 - 包含IP地址总数:$2^{10}$ = 1024个地址(包含4个原始/24块)[^1]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值