给定三个数a,b,c,请问满足以下3个条件的xy组合数有多少个?

给定三个数a,b,c,请问满足以下3个条件的xy组合数有多少个?

提示:阿里笔试原题,懂得双指针解决单调问题的优化方法


题目

给你3个数abc,请问你有多少这样的xy组合数?使得下列三个条件成立?
a<= x^^2 <=b
a<= y^^3 <=b
x^^2 - y^^3 <=c
abc数量的范围10^^6


一、审题

示例:这就不需要我再举例子了吧


二、解题

abc数量的范围10^^6
也就是说你不能设计o(n^^ 2) 的算法,否则就是10^^12的复杂度,过不了的
这个题要优化为o(n) 的算法复杂度

大流程也很容易,学过就熟悉了:
——1.先罗列x,放入数组xArr
——2.罗列y,放入数组yArr

既然xy他们都是递增的,自然就有单调性,双指针解决没问题【这个思想要牢记

——然后双指针p1,p2,找满足条件3的位置p2,则可以统计:每次以p1开头的x,达到条件3的位置p2的y,组合xy有几个? N2-p2个,因为p2的右边y更大,则条件3得到的值更小,均符合条件。
但是p1的x - p2左边的y们是不会满足条件的,y太小不行
因此真题p1,p2往右挪一遍,复杂度就是了o(n)
看图:
图1

看代码:

public static int findHowMany(int a, int b, int c){
        //abc都正整数
        //    1.先罗列x,放入数组xArr
//    2.罗列y,放入数组yArr
        List<Integer> xArr = new ArrayList<>();//因为不知道有多少x,只能是静态数组了
        List<Integer> yArr = new ArrayList<>();

        int x = 1;

        while (true){
            int t2 = x * x;
            int t3 = x * t2;
            if (a <= t2 && t2 <= b) xArr.add(t2);//直接记平方,待会用即可
            if (a <= t3 && t3 <= b) yArr.add(t3);
            if (t3 > b) break;//当t3都越界了,那就没必要玩了
            x++;
        }

        int p1 = 0;
        int p2 = 0;
        int N1 = xArr.size();
        int N2 = yArr.size();
        int ans = 0;
        while (p1 < N1){
            int d = xArr.get(p1) - yArr.get(p2);
            if (d <= c) {
                ans += N2 - p2;
                p1++;//满足就算当前x已经有这么多组合,下一步,以下一个x开头,x增大,势必又有很多答案
            }
            else p2++;//条件不足,则y太小,需要增加y
            if (p2 == N2) break;
        }

        return ans;
    }

测试:

public static void test(){
        Scanner in = new Scanner(System.in);
        int a = in.nextInt();
        int b = in.nextInt();
        int c = in.nextInt();

        int ans = findHowMany(a, b, c);
        System.out.println(ans);
    }

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

总结

提示:重要经验:

1)双指针是解决单调问题的良药
2)调代码就是要慢慢写,然后抠清楚边界,多练习,找感觉!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰露可乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值