- Choose the invariant that makes a window valid or useful.
- Advance the right boundary and add the new element.
- Move the left boundary only as needed while maintaining the invariant and updating the answer.
Code notes
- 105 lines of Java from the credited upstream file 3015.java.
- The implementation visibly relies on sequence storage.
- 6 loop blocks detected.
Complexity
Confirm that neither pointer moves backwards; if so, the scan is usually linear apart from the window’s data-structure operations.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1class Solution {2 public int[] countOfPairs(int n, int x, int y) {3 if (x > y) {4 final int temp = x;5 x = y;6 y = temp;7 }8 9 final int ringLen = y - x + 1;10 final int leftLineLen = x - 1;11 final int rightLineLen = n - y;12 13 int[] ans = new int[n];14 ans = addVectors(ans, bothInRing(n, ringLen));15 ans = addVectors(ans, bothInTheSameLine(n, leftLineLen));16 ans = addVectors(ans, bothInTheSameLine(n, rightLineLen));17 ans = addVectors(ans, lineToRing(n, leftLineLen, ringLen));18 ans = addVectors(ans, lineToRing(n, rightLineLen, ringLen));19 ans = addVectors(ans, lineToLine(n, x, y, leftLineLen, rightLineLen));20 for (int i = 0; i < ans.length; ++i)21 ans[i] *= 2;22 return ans;23 }24 25 26 27 private int[] bothInRing(int n, int ringLen) {28 int[] res = new int[n];29 for (int k = 1; k <= (ringLen - 1) / 2; ++k)30 res[k - 1] += ringLen;31 if (ringLen % 2 == 0)32 res[ringLen / 2 - 1] += ringLen / 2;33 return res;34 }35 36 37 38 private int[] bothInTheSameLine(int n, int lineLen) {39 int[] res = new int[n];40 for (int k = 1; k <= lineLen; ++k)41 res[k - 1] += lineLen - k;42 return res;43 }44 45 46 47 48 private int[] lineToRing(int n, int lineLen, int ringLen) {49 int[] res = new int[n];50 for (int k = 1; k <= lineLen + ringLen; ++k) {51 52 53 54 55 56 final int maxInRingLen = Math.min(k - 1, ringLen / 2);57 58 final int minInRingLen = Math.max(0, k - lineLen);59 if (minInRingLen <= maxInRingLen) {60 61 62 63 64 65 66 res[k - 1] += (maxInRingLen - minInRingLen + 1) * 2;67 if (minInRingLen == 0)68 69 res[k - 1] -= 1;70 if (maxInRingLen * 2 == ringLen)71 72 73 74 res[k - 1] -= 1;75 }76 }77 return res;78 }79 80 81 82 private int[] lineToLine(int n, int x, int y, int leftLineLen, int rightLineLen) {83 int[] res = new int[n];84 for (int k = 1; k <= leftLineLen + rightLineLen + 2; ++k) {85 86 87 88 89 90 final int maxInLeft = Math.min(leftLineLen, k - 1 - (x < y ? 1 : 0));91 92 final int minInLeft = Math.max(1, k - rightLineLen - (x < y ? 1 : 0));93 if (minInLeft <= maxInLeft)94 res[k - 1] += maxInLeft - minInLeft + 1;95 }96 return res;97 }98 99 private int[] addVectors(int[] a, int[] b) {100 for (int i = 0; i < a.length; ++i)101 a[i] += b[i];102 return a;103 }104}105