Three Numbers in Java Given three positive numbers A, B, and C. Find the number of positive
  integers less than D that are divisible by either of A, B or C.
  
  Input format
  
  The 1st argument given is an Integer A. The 2nd argument given is an
  Integer B. The 3rd argument given is an Integer C. The 4th argument
  given is an Integer D.
  
  Output Format
  
  Return an Integer X, the number of positive integers that are
  divisible by either of A, B, or C.
  
  Constraints
  
  1 &lt;= A, B, C, D &lt;= 1e9
  
  For Example
  
  Input:
  
  A = 2
  
  B = 3
  
  C = 4
  
  D = 10 
  
  Output:
  
  6
  
  Explanation:
  
  positive numbers less than D that are divisible by either of A, B or C are    2, 3, 4, 6, 8, 9


My approach:

import java.math.BigInteger;

public class Solution {
    public int solve(int A, int B, int C, int D) {
        BigInteger numDivA = BigInteger.valueOf((D - 1)/A);

        BigInteger numDivB = BigInteger.valueOf((D - 1)/B);

        BigInteger numDivC = BigInteger.valueOf((D - 1)/C);

        BigInteger newA = BigInteger.valueOf(A);

        BigInteger newB = BigInteger.valueOf(B);

        BigInteger newC = BigInteger.valueOf(C);

        BigInteger newD = BigInteger.valueOf(D);

        BigInteger limit = new BigInteger("1000000000");

        BigInteger lcmAB = (newA.divide(hcf(newA, newB))).multiply(newB);

        BigInteger lcmAC = (newC.divide(hcf(newA, newC))).multiply(newA);

        BigInteger lcmBC = (newB.divide(hcf(newB, newC))).multiply(newC);

        BigInteger lcmABC = lcmAB.divide(hcf(lcmAB,newC)).multiply(newC);     

        BigInteger numDivAB = newD.subtract(BigInteger.ONE).divide(lcmAB);

        BigInteger numDivBC = newD.subtract(BigInteger.ONE).divide(lcmBC);        

        BigInteger numDivAC = newD.subtract(BigInteger.ONE).divide(lcmAC);

        BigInteger numDivABC = newD.subtract(BigInteger.ONE).divide(lcmABC);                

        BigInteger numTotal = (((((numDivA.add(numDivB)).add(numDivC)).subtract(numDivAB)).subtract(numDivBC)).subtract(numDivAC)).add(numDivABC);

        return (numTotal.mod(limit)).intValue();
    }

    private BigInteger hcf (BigInteger a, BigInteger b) {

        BigInteger hcf = a.gcd(b);

        return hcf;
    }


}


I have the following questions with regards to the above code:


How can I further improve my approach?
Is there a better way to solve this question?
Are there any grave code violations that I have committed?
Can space and time complexity be further improved?
Have I gone too overboard by using BigInteger?


Reference
1e9 is only 1 billion, which will fit into a standard integer range of 2 billion some.

The hcf function is unexpected, because it's just a wrapper for BigInteger. I think just using the built in GCD function would be better than making your own method that calls a standard function. If it's critical to the algorithm understanding that we think of a highest common factor instead of a greatest common denominator, then keep the function. If you do keep it, though, use the full name instead of an abbreviation i.e. private BigInteger highestCommonFactor.

I looked at your code and expected to see a loop. I'm assuming you've worked out the math to do this without loops, which is good and probably more efficient. But, I don't really know how this would work, and would be worried someone else looking at the code would have the same problem. A code comment indicating what mathematical principles, or even the name of a theorem, would help immensely.