You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java无限IntStream:求三流共有的最小元素的优化实现问询

更高效的解法:利用数列特性+双指针法

绝对有更高效的解法!暴力嵌套循环虽然直观,但会做大量无意义的遍历,完全没用到这三个数列的数学特性——其实这里有个关键的优化点:所有六角数都是三角数!

先理清楚数学特性

先看三个数列的公式:

  • 三角数:T(n) = n(n+1)/2
  • 五角数:P(n) = n(3n-1)/2
  • 六角数:H(n) = n(2n-1)

把六角数的公式代入三角数公式,可以证明:对于任意六角数H(k),当三角数的索引m = 2k-1时,T(m) = H(k)。也就是说六角数是三角数的子集,所以我们根本不需要再比对三角数序列——只要找到同时属于五角数和六角数的最小数,它自动就是三个序列的共同元素!

基于双指针的线性遍历解法

因为五角数和六角数的序列都是严格递增的,我们可以用类似合并有序数组的双指针思路,分别遍历两个序列,一步步逼近目标值,时间复杂度是O(n)(n是找到目标时的较大序列索引),比暴力嵌套的O(n²)高效太多。

代码实现(非Stream版,更直观)

public class CommonPolyNumberFinder {
    public static void main(String[] args) {
        // 初始化两个序列的起始值(对应题目给出的起始索引)
        long pentagonal = 166L * (3 * 166 - 1) / 2;
        long hexagonal = 144L * (2 * 144 - 1);
        
        int pentaIndex = 167;
        int hexaIndex = 145;
        
        while (true) {
            if (pentagonal == hexagonal) {
                System.out.println("三个序列的最小共同元素:" + pentagonal);
                break;
            } else if (hexagonal < pentagonal) {
                // 六角数更小,生成下一个六角数
                hexagonal = hexaIndex * (2L * hexaIndex - 1);
                hexaIndex++;
            } else {
                // 五角数更小,生成下一个五角数
                pentagonal = pentaIndex * (3L * pentaIndex - 1) / 2;
                pentaIndex++;
            }
        }
    }
}

Stream迭代器版(保留Stream风格)

如果想保留Stream的生成逻辑,可以用Stream的迭代器来手动控制元素获取,避免无限Stream的遍历失控:

import java.util.stream.IntStream;
import java.util.PrimitiveIterator;

public class StreamBasedPolyFinder {
    public static void main(String[] args) {
        // 生成五角数的迭代器
        PrimitiveIterator.OfInt pentaIterator = IntStream.iterate(166, i -> i + 1)
                .map(i -> i * (3 * i - 1) / 2)
                .iterator();
        // 生成六角数的迭代器
        PrimitiveIterator.OfInt hexaIterator = IntStream.iterate(144, i -> i + 1)
                .map(i -> i * (2 * i - 1))
                .iterator();
        
        long currentPenta = pentaIterator.nextLong();
        long currentHexa = hexaIterator.nextLong();
        
        while (true) {
            if (currentPenta == currentHexa) {
                System.out.println("三个序列的最小共同元素:" + currentPenta);
                break;
            } else if (currentHexa < currentPenta) {
                currentHexa = hexaIterator.nextLong();
            } else {
                currentPenta = pentaIterator.nextLong();
            }
        }
    }
}

关键优化点说明

  1. 减少维度:利用六角数是三角数的特性,直接把三维比对降到二维,砍掉了一个序列的遍历
  2. 线性遍历:双指针法每一步都只生成下一个需要的元素,没有任何无用的计算,比暴力嵌套的多层循环效率提升非常明显
  3. 避免溢出:用long类型存储计算结果,因为数列增长很快,int类型会很快溢出(比如题目里的起始值用int计算已经接近上限了)

内容的提问来源于stack exchange,提问作者bisarch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:14:43