编程之美_010快速寻找满足条件的两个数

本文介绍了一种在数组中寻找两个数使它们的和等于特定值的方法。通过排序数组并使用两端指针扫描的方式,该算法能在O(N*logN)的时间复杂度内找到符合条件的数对。
// 快速寻找满足条件的两个数
// 数组中两个数的和满足指定结果
public class Test
{
    static int[] arr =
    {
            1, 5, 9, 3, 4, 7, 6, 2, 8
    };
    static int maxIndex = arr.length - 1;// 索引最大值
    static int sum = 11;// 求两个数的和等于的值

    public static void main(String[] args)
    {
        find1(arr);
    }

    // 1.所有数字两两组合,计算;时间复杂度O(n*n)
    // 2.先把数组排序,然后利用二分查找在数组中查找,判断sum-arr[i]是否在数组中;时间复杂度O(n*longn)
    // 3.先对数组排序i=0,j=n-1,如果:sum<arr[i]+arr[j] i++;如果:sum<arr[i]+arr[j] j--
    // 如果有序,直接两个指针两端扫描,时间O(N);如果无序,先排序后两端扫描,时间O(N*logN+N)=O(N*logN),空间始终都为O(1)
    static void find1(int[] arr)
    {
        Arrays.sort(arr);// 对数组排序
        for (int i = 0, j = maxIndex; i < j;)
        {
            if (arr[i] + arr[j] == sum)
            {
                System.out.println(sum + " = " + arr[i] + " + " + arr[j]);
                i++;// 没有这一句死循环
            }
            else if (arr[i] + arr[j] < sum)
            {
                i++;
            }
            else
            {
                j--;
            }
        }
    }
}

在C++编程中,若要寻找个质数,其和为给定值 `s`,并且它们的乘积最大,则可以采用以下方法: ### 方法概述 1. **筛选质数**:使用埃拉托色尼筛法(Sieve of Eratosthenes)预先筛选出小于 `s` 的所有质数。 2. **遍历质数**:从最小的质数开始,检查是否存在另一个质数,使得者的和等于 `s`。 3. **计算最大乘积**:对于每一对满足条件的质数,计算它们的乘积,并记录最大值。 ### 算法实现 以下是C++代码示例: ```cpp #include <iostream> #include <vector> using namespace std; // 使用埃拉托色尼筛法生成所有小于s的质数 vector<bool> sieve(int s) { vector<bool> is_prime(s, true); is_prime[0] = is_prime[1] = false; for (int i = 2; i * i < s; ++i) { if (is_prime[i]) { for (int j = i * i; j < s; j += i) { is_prime[j] = false; } } } return is_prime; } // 寻找和为s的个质数,并返回它们的最大乘积 int max_prime_product(int s, const vector<bool>& is_prime) { int max_product = 0; for (int i = 2; i <= s / 2; ++i) { if (is_prime[i] && is_prime[s - i]) { int product = i * (s - i); if (product > max_product) { max_product = product; } } } return max_product; } int main() { int s; cout << "请输入一个正整数s:"; cin >> s; // 生成质数表 vector<bool> is_prime = sieve(s); // 计算最大乘积 int result = max_prime_product(s, is_prime); if (result > 0) { cout << "和为" << s << "的个质数的最大乘积是:" << result << endl; } else { cout << "无法找到和为" << s << "的个质数。" << endl; } return 0; } ``` ### 代码说明 1. **筛法生成质数表**:通过埃拉托色尼筛法生成小于 `s` 的所有质数的布尔数组 `is_prime`。 2. **寻找质数对**:从 `2` 到 `s/2` 遍历,检查 `i` 和 `s - i` 是否均为质数。 3. **计算最大乘积**:对于每一对满足条件的质数,计算它们的乘积,并记录最大值。 ### 示例 假设输入 `s = 20`: - 可能的质数对包括 `(3, 17)`、`(7, 13)`。 - 它们的乘积分别为 `51` 和 `91`,因此最大乘积为 `91`。 ### 时间复杂度 - **筛法生成质数**:时间复杂度为 $O(n \log \log n)$,其中 $n = s$。 - **遍历质数对**:时间复杂度为 $O(s)$。 ### 空间复杂度 - 使用了一个大小为 $s$ 的布尔数组来存储质数信息,空间复杂度为 $O(s)$。 ### 注意事项 - 如果 `s` 小于 `4`,则无法找到个质数之和为 `s`。 - 若 `s` 为偶数,则可能存在多个质数对满足条件。 - 若 `s` 为奇数,则其中一个质数必须为 `2`,因为偶数加奇数才能得到奇数。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值