- Translate each rule into one explicit state update.
- Maintain the invariant after every processed item.
- Return the accumulated state once all relevant input has been handled.
Code notes
- 117 lines of Java from the credited upstream file 3549.java.
- The implementation visibly relies on sequence storage.
- 11 loop blocks detected.
Complexity
Count the number and nesting of passes over the input, then include the maintained containers in the memory estimate.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1class Complex {2 public double real;3 public double imag;4 5 public Complex(double real, double imag) {6 this.real = real;7 this.imag = imag;8 }9 10 public Complex add(Complex other) {11 return new Complex(this.real + other.real, this.imag + other.imag);12 }13 14 public Complex subtract(Complex other) {15 return new Complex(this.real - other.real, this.imag - other.imag);16 }17 18 public Complex multiply(Complex other) {19 return new Complex(this.real * other.real - this.imag * other.imag,20 this.real * other.imag + this.imag * other.real);21 }22 23 public Complex divide(double scalar) {24 return new Complex(this.real / scalar, this.imag / scalar);25 }26}27 28class Solution {29 public long[] multiply(int[] poly1, int[] poly2) {30 final int n1 = poly1.length;31 final int n2 = poly2.length;32 final int n = n1 + n2 - 1;33 final int sz = 1 << bitLength(n - 1);34 35 36 Complex[] a = new Complex[sz];37 Complex[] b = new Complex[sz];38 39 40 for (int i = 0; i < sz; ++i) {41 a[i] = new Complex(0, 0);42 b[i] = new Complex(0, 0);43 }44 45 46 for (int i = 0; i < n1; ++i)47 a[i] = new Complex(poly1[i], 0);48 49 for (int i = 0; i < n2; ++i)50 b[i] = new Complex(poly2[i], 0);51 52 53 fft(a, false);54 fft(b, false);55 56 57 for (int i = 0; i < sz; ++i)58 a[i] = a[i].multiply(b[i]);59 60 61 fft(a, true);62 63 64 long[] ans = new long[n];65 66 for (int i = 0; i < n; ++i)67 ans[i] = Math.round(a[i].real);68 69 return ans;70 }71 72 private void fft(Complex[] a, boolean inverse) {73 final int n = a.length;74 75 76 for (int i = 1, j = 0; i < n; ++i) {77 int bit = n >> 1;78 for (; (j & bit) != 0; bit >>= 1)79 j ^= bit;80 j ^= bit;81 if (i < j)82 swap(a, i, j);83 }84 85 86 for (int len = 2; len <= n; len *= 2) {87 final double angle = 2 * Math.PI / len * (inverse ? -1 : 1);88 final Complex wLen = new Complex(Math.cos(angle), Math.sin(angle));89 for (int i = 0; i < n; i += len) {90 Complex w = new Complex(1, 0);91 for (int j = 0; j < len / 2; ++j) {92 final Complex u = a[i + j];93 final Complex v = a[i + j + len / 2].multiply(w);94 a[i + j] = u.add(v);95 a[i + j + len / 2] = u.subtract(v);96 w = w.multiply(wLen);97 }98 }99 }100 101 102 if (inverse)103 for (int i = 0; i < n; ++i)104 a[i] = a[i].divide(n);105 }106 107 private void swap(Complex[] a, int i, int j) {108 Complex temp = a[i];109 a[i] = a[j];110 a[j] = temp;111 }112 113 private int bitLength(int n) {114 return Integer.SIZE - Integer.numberOfLeadingZeros(n);115 }116}117