当前位置: 首页 > article >正文

两数之和笔记

对于一个非常庞大的数组,我们可以使用一些优化方法来寻找其中所有满足“两数之和不大于 `n`” 的数对。直接使用双重循环会导致时间复杂度为 `O(N^2)`,这在数组庞大时可能会非常慢。这里我们可以使用 **双指针法** 来优化该问题,将时间复杂度降为 `O(N log N)`。

### 算法思路
1. **排序数组**:首先对数组进行升序排序,时间复杂度为 `O(N log N)`。
2. **双指针法**:
   - 初始化两个指针 `left` 和 `right`,分别指向数组的起始和末尾。
   - 如果 `arr[left] + arr[right] <= n`,则从 `left` 到 `right` 之间的所有数与 `arr[left]` 的和都满足要求,因为数组已排序。记录所有这些数对,并将 `left` 向右移动一位。
   - 如果 `arr[left] + arr[right] > n`,则将 `right` 左移一位,尝试缩小数对的和。
3. 重复步骤2,直到 `left` 与 `right` 指针相遇。

### 示例代码
以下是C++实现的代码示例:

```cpp
#include <iostream>
#include <vector>
#include <algorithm>

std::vector<std::pair<int, int>> findPairsWithSumLessThanN(std::vector<int>& arr, int n) {
    std::vector<std::pair<int, int>> result;

    // 对数组进行排序
    std::sort(arr.begin(), arr.end());

    int left = 0;
    int right = arr.size() - 1;

    while (left < right) {
        // 检查当前两个数的和
        if (arr[left] + arr[right] <= n) {
            // 从 left 到 right 之间的所有数与 arr[left] 组成的数对都符合条件
            for (int i = left + 1; i <= right; ++i) {
                result.push_back({arr[left], arr[i]});
            }
            // 移动左指针
            ++left;
        } else {
            // 移动右指针
            --right;
        }
    }

    return result;
}

int main() {
    std::vector<int> arr = {1, 3, 5, 7, 9};
    int n = 10;

    std::vector<std::pair<int, int>> result = findPairsWithSumLessThanN(arr, n);

    std::cout << "Pairs with sum less than or equal to " << n << ":\n";
    for (const auto& pair : result) {
        std::cout << "(" << pair.first << ", " << pair.second << ")\n";
    }

    return 0;
}
```

### 代码说明
1. **排序数组**:先对数组进行排序,以便使用双指针法。
2. **双指针寻找数对**:
   - 如果 `arr[left] + arr[right] <= n`,则从 `left + 1` 到 `right` 之间的所有元素与 `arr[left]` 的和都满足条件,记录这些数对。
   - 如果 `arr[left] + arr[right] > n`,则将 `right` 左移一位,尝试找更小的数对。
3. **结果输出**:输出所有符合条件的数对。

### 复杂度分析
- **时间复杂度**:排序为 `O(N log N)`,双指针部分为 `O(N)`,总的时间复杂度为 `O(N log N)`。
- **空间复杂度**:`O(N)`,用于存储符合条件的数对。


http://www.kler.cn/a/377884.html

相关文章:

  • LGMRec:结合局部与全局图学习的多模态推荐系统
  • vuex如何进行状态管理?
  • PostgreSQL 的历史
  • oracle: create new database
  • 安装fast_bev环境
  • (2024.12)Ubuntu20.04安装openMVS<成功>.colmap<成功>和openMVG<失败>记录
  • redis v6.0.16 安装 基于Ubuntu 22.04
  • (蓝桥杯C/C++)——STL(上)
  • 使用代理和不使用代理request获取host、scheme、url、ip区别
  • FOYA传媒科技招聘
  • 第五项修炼—系统思考
  • 二分查找算法—C++
  • 【机器学习】18. 反向传播 Backpropagation algorithm, 学习率,动量Momenetum, Xavier,梯度消失
  • 实用篇:Postman历史版本下载
  • UI设计公司—兰亭妙微—提供轨道交通行业UI设计
  • mysql5安装
  • Qt6 CMake 中引入 Qt Linguist 翻译功能
  • 服务器数据恢复—RAID5阵列中部分成员盘重组RAID5阵列后如何恢复原raid5阵列数据?
  • 九识智能与徐工汽车达成战略合作,共绘商用车未来新蓝图
  • 基于Spring Boot的信息学科平台系统开发指南
  • 将 IBM WatsonX 数据与 Milvus 结合使用,构建用于知识检索的智能 Slack 机器人
  • 鸿蒙生态崛起:开发者机遇与挑战并存
  • 【书籍推荐】使用 MATLAB 算法进行合成孔径雷达信号处理【附MATLAB代码】
  • 整数大小比较c++
  • Win11GBK, idea2024.2.4, 使用Gradle8.8本地安装构建,不使用包装器, 解决utf-8乱码问题, 笔记241028
  • SpringBoot项目如何设置定时任务总开关