diff --git a/src/main/java/g0401_0500/s0492_construct_the_rectangle/Solution.java b/src/main/java/g0401_0500/s0492_construct_the_rectangle/Solution.java
new file mode 100644
index 000000000..87c70a04b
--- /dev/null
+++ b/src/main/java/g0401_0500/s0492_construct_the_rectangle/Solution.java
@@ -0,0 +1,21 @@
+package g0401_0500.s0492_construct_the_rectangle;
+
+// #Easy #Math
+
+public class Solution {
+ /*
+ Algorithm:
+ - start with an index i from the square root all the way to 1;
+ - if at any time, area % i == 0 (so i is a divisor of area), then it's the closest solution.
+ */
+ public int[] constructRectangle(int area) {
+ int low = (int) Math.sqrt(area);
+ while (low > 0) {
+ if (area % low == 0) {
+ return new int[] {area / low, low};
+ }
+ low--;
+ }
+ return new int[] {0, 0};
+ }
+}
diff --git a/src/main/java/g0401_0500/s0492_construct_the_rectangle/readme.md b/src/main/java/g0401_0500/s0492_construct_the_rectangle/readme.md
new file mode 100644
index 000000000..351724075
--- /dev/null
+++ b/src/main/java/g0401_0500/s0492_construct_the_rectangle/readme.md
@@ -0,0 +1,35 @@
+492\. Construct the Rectangle
+
+Easy
+
+A web developer needs to know how to design a web page's size. So, given a specific rectangular web page’s area, your job by now is to design a rectangular web page, whose length L and width W satisfy the following requirements:
+
+1. The area of the rectangular web page you designed must equal to the given target area.
+2. The width `W` should not be larger than the length `L`, which means `L >= W`.
+3. The difference between length `L` and width `W` should be as small as possible.
+
+Return _an array `[L, W]` where `L` and `W` are the length and width of the web page you designed in sequence._
+
+**Example 1:**
+
+**Input:** area = 4
+
+**Output:** [2,2]
+
+**Explanation:** The target area is 4, and all the possible ways to construct it are [1,4], [2,2], [4,1]. But according to requirement 2, [1,4] is illegal; according to requirement 3, [4,1] is not optimal compared to [2,2]. So the length L is 2, and the width W is 2.
+
+**Example 2:**
+
+**Input:** area = 37
+
+**Output:** [37,1]
+
+**Example 3:**
+
+**Input:** area = 122122
+
+**Output:** [427,286]
+
+**Constraints:**
+
+* 1 <= area <= 107
\ No newline at end of file
diff --git a/src/main/java/g0401_0500/s0493_reverse_pairs/Solution.java b/src/main/java/g0401_0500/s0493_reverse_pairs/Solution.java
new file mode 100644
index 000000000..9533c9821
--- /dev/null
+++ b/src/main/java/g0401_0500/s0493_reverse_pairs/Solution.java
@@ -0,0 +1,33 @@
+package g0401_0500.s0493_reverse_pairs;
+
+// #Hard #Array #Binary_Search #Ordered_Set #Divide_and_Conquer #Segment_Tree #Binary_Indexed_Tree
+// #Merge_Sort
+
+import java.util.Arrays;
+
+public class Solution {
+ // reference:
+ // https://discuss.leetcode.com/topic/78933/very-short-and-clear-mergesort-bst-java-solutions
+ public int reversePairs(int[] nums) {
+ return mergeSort(nums, 0, nums.length - 1);
+ }
+
+ private int mergeSort(int[] nums, int start, int end) {
+ if (start >= end) {
+ return 0;
+ }
+ int mid = start + (end - start) / 2;
+ int cnt = mergeSort(nums, start, mid) + mergeSort(nums, mid + 1, end);
+ for (int i = start; i <= mid; i++) {
+ // it has to be 2.0 instead of 2, otherwise it's going to stack overflow, i.e. test3 is
+ // going to fail
+ int j = mid + 1;
+ while (j <= end && nums[i] > nums[j] * 2.0) {
+ j++;
+ }
+ cnt += j - (mid + 1);
+ }
+ Arrays.sort(nums, start, end + 1);
+ return cnt;
+ }
+}
diff --git a/src/main/java/g0401_0500/s0493_reverse_pairs/readme.md b/src/main/java/g0401_0500/s0493_reverse_pairs/readme.md
new file mode 100644
index 000000000..fe1cb2e74
--- /dev/null
+++ b/src/main/java/g0401_0500/s0493_reverse_pairs/readme.md
@@ -0,0 +1,24 @@
+493\. Reverse Pairs
+
+Hard
+
+Given an integer array `nums`, return _the number of **reverse pairs** in the array_.
+
+A reverse pair is a pair `(i, j)` where `0 <= i < j < nums.length` and `nums[i] > 2 * nums[j]`.
+
+**Example 1:**
+
+**Input:** nums = [1,3,2,3,1]
+
+**Output:** 2
+
+**Example 2:**
+
+**Input:** nums = [2,4,3,5,1]
+
+**Output:** 3
+
+**Constraints:**
+
+* 1 <= nums.length <= 5 * 104
+* -231 <= nums[i] <= 231 - 1
\ No newline at end of file
diff --git a/src/main/java/g0401_0500/s0495_teemo_attacking/Solution.java b/src/main/java/g0401_0500/s0495_teemo_attacking/Solution.java
new file mode 100644
index 000000000..ea1c68d21
--- /dev/null
+++ b/src/main/java/g0401_0500/s0495_teemo_attacking/Solution.java
@@ -0,0 +1,25 @@
+package g0401_0500.s0495_teemo_attacking;
+
+// #Easy #Array #Simulation
+
+public class Solution {
+ public int findPoisonedDuration(int[] timeSeries, int duration) {
+ if (duration == 0) {
+ return 0;
+ }
+ int start = timeSeries[0];
+ int end = timeSeries[0] + duration - 1;
+ int poisonDuration = end - start + 1;
+ for (int i = 1; i < timeSeries.length; i++) {
+ if (timeSeries[i] <= end) {
+ poisonDuration += (duration - (end - timeSeries[i] + 1));
+ end += (duration - (end - timeSeries[i] + 1));
+ } else {
+ start = timeSeries[i];
+ end = timeSeries[i] + duration - 1;
+ poisonDuration += end - start + 1;
+ }
+ }
+ return poisonDuration;
+ }
+}
diff --git a/src/main/java/g0401_0500/s0495_teemo_attacking/readme.md b/src/main/java/g0401_0500/s0495_teemo_attacking/readme.md
new file mode 100644
index 000000000..d04e932ff
--- /dev/null
+++ b/src/main/java/g0401_0500/s0495_teemo_attacking/readme.md
@@ -0,0 +1,37 @@
+495\. Teemo Attacking
+
+Easy
+
+Our hero Teemo is attacking an enemy Ashe with poison attacks! When Teemo attacks Ashe, Ashe gets poisoned for a exactly `duration` seconds. More formally, an attack at second `t` will mean Ashe is poisoned during the **inclusive** time interval `[t, t + duration - 1]`. If Teemo attacks again **before** the poison effect ends, the timer for it is **reset**, and the poison effect will end `duration` seconds after the new attack.
+
+You are given a **non-decreasing** integer array `timeSeries`, where `timeSeries[i]` denotes that Teemo attacks Ashe at second `timeSeries[i]`, and an integer `duration`.
+
+Return _the **total** number of seconds that Ashe is poisoned_.
+
+**Example 1:**
+
+**Input:** timeSeries = [1,4], duration = 2
+
+**Output:** 4
+
+**Explanation:** Teemo's attacks on Ashe go as follows: - At second 1, Teemo attacks, and Ashe is poisoned for seconds 1 and 2. - At second 4, Teemo attacks, and Ashe is poisoned for seconds 4 and 5. Ashe is poisoned for seconds 1, 2, 4, and 5, which is 4 seconds in total.
+
+**Example 2:**
+
+**Input:** timeSeries = [1,2], duration = 2
+
+**Output:** 3
+
+**Explanation:**
+
+Teemo's attacks on Ashe go as follows:
+
+- At second 1, Teemo attacks, and Ashe is poisoned for seconds 1 and 2.
+
+- At second 2 however, Teemo attacks again and resets the poison timer. Ashe is poisoned for seconds 2 and 3. Ashe is poisoned for seconds 1, 2, and 3, which is 3 seconds in total.
+
+**Constraints:**
+
+* 1 <= timeSeries.length <= 104
+* 0 <= timeSeries[i], duration <= 107
+* `timeSeries` is sorted in **non-decreasing** order.
\ No newline at end of file
diff --git a/src/main/java/g0401_0500/s0496_next_greater_element_i/Solution.java b/src/main/java/g0401_0500/s0496_next_greater_element_i/Solution.java
new file mode 100644
index 000000000..f3c780993
--- /dev/null
+++ b/src/main/java/g0401_0500/s0496_next_greater_element_i/Solution.java
@@ -0,0 +1,38 @@
+package g0401_0500.s0496_next_greater_element_i;
+
+// #Easy #Array #Hash_Table #Stack #Monotonic_Stack
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Solution {
+ public int[] nextGreaterElement(int[] nums1, int[] nums2) {
+ Map indexMap = new HashMap<>();
+ for (int i = 0; i < nums2.length; i++) {
+ indexMap.put(nums2[i], i);
+ }
+
+ for (int i = 0; i < nums1.length; i++) {
+ int num = nums1[i];
+ int index = indexMap.get(num);
+ if (index == nums2.length - 1) {
+ nums1[i] = -1;
+ } else {
+ boolean found = false;
+ while (index < nums2.length) {
+ if (nums2[index] > num) {
+ nums1[i] = nums2[index];
+ found = true;
+ break;
+ }
+ index++;
+ }
+ if (!found) {
+ nums1[i] = -1;
+ }
+ }
+ }
+
+ return nums1;
+ }
+}
diff --git a/src/main/java/g0401_0500/s0496_next_greater_element_i/readme.md b/src/main/java/g0401_0500/s0496_next_greater_element_i/readme.md
new file mode 100644
index 000000000..ce964c577
--- /dev/null
+++ b/src/main/java/g0401_0500/s0496_next_greater_element_i/readme.md
@@ -0,0 +1,50 @@
+496\. Next Greater Element I
+
+Easy
+
+The **next greater element** of some element `x` in an array is the **first greater** element that is **to the right** of `x` in the same array.
+
+You are given two **distinct 0-indexed** integer arrays `nums1` and `nums2`, where `nums1` is a subset of `nums2`.
+
+For each `0 <= i < nums1.length`, find the index `j` such that `nums1[i] == nums2[j]` and determine the **next greater element** of `nums2[j]` in `nums2`. If there is no next greater element, then the answer for this query is `-1`.
+
+Return _an array_ `ans` _of length_ `nums1.length` _such that_ `ans[i]` _is the **next greater element** as described above._
+
+**Example 1:**
+
+**Input:** nums1 = [4,1,2], nums2 = [1,3,4,2]
+
+**Output:** [-1,3,-1]
+
+**Explanation:**
+
+The next greater element for each value of nums1 is as follows:
+
+- 4 is underlined in nums2 = [1,3,4,2]. There is no next greater element, so the answer is -1.
+
+- 1 is underlined in nums2 = [1,3,4,2]. The next greater element is 3.
+
+- 2 is underlined in nums2 = [1,3,4,2]. There is no next greater element, so the answer is -1.
+
+**Example 2:**
+
+**Input:** nums1 = [2,4], nums2 = [1,2,3,4]
+
+**Output:** [3,-1]
+
+**Explanation:**
+
+The next greater element for each value of nums1 is as follows:
+
+- 2 is underlined in nums2 = [1,2,3,4]. The next greater element is 3.
+
+- 4 is underlined in nums2 = [1,2,3,4]. There is no next greater element, so the answer is -1.
+
+**Constraints:**
+
+* `1 <= nums1.length <= nums2.length <= 1000`
+* 0 <= nums1[i], nums2[i] <= 104
+* All integers in `nums1` and `nums2` are **unique**.
+* All the integers of `nums1` also appear in `nums2`.
+
+**Follow up:** Could you find an `O(nums1.length + nums2.length)` solution?
\ No newline at end of file
diff --git a/src/main/java/g0401_0500/s0497_random_point_in_non_overlapping_rectangles/Solution.java b/src/main/java/g0401_0500/s0497_random_point_in_non_overlapping_rectangles/Solution.java
new file mode 100644
index 000000000..3c6c5d624
--- /dev/null
+++ b/src/main/java/g0401_0500/s0497_random_point_in_non_overlapping_rectangles/Solution.java
@@ -0,0 +1,53 @@
+package g0401_0500.s0497_random_point_in_non_overlapping_rectangles;
+
+// #Medium #Math #Binary_Search #Prefix_Sum #Ordered_Set #Randomized #Reservoir_Sampling
+
+import java.security.SecureRandom;
+
+public class Solution {
+ private final int[] weights;
+ private final int[][] rects;
+ private final SecureRandom random;
+
+ public Solution(int[][] rects) {
+ this.weights = new int[rects.length];
+ this.rects = rects;
+ this.random = new SecureRandom();
+ for (int i = 0; i < rects.length; i++) {
+ int[] rect = rects[i];
+ int count = (1 + rect[2] - rect[0]) * (1 + rect[3] - rect[1]);
+ weights[i] = (i == 0 ? 0 : weights[i - 1]) + count;
+ }
+ }
+
+ public int[] pick() {
+ int picked = 1 + random.nextInt(weights[weights.length - 1]);
+ int idx = findGreaterOrEqual(picked);
+ return getRandomPoint(idx);
+ }
+
+ private int findGreaterOrEqual(int target) {
+ int left = 0;
+ int right = weights.length - 1;
+ while (left + 1 < right) {
+ int mid = left + (right - left) / 2;
+ if (weights[mid] >= target) {
+ right = mid;
+ } else {
+ left = mid + 1;
+ }
+ }
+ return weights[left] >= target ? left : right;
+ }
+
+ private int[] getRandomPoint(int idx) {
+ int[] r = rects[idx];
+ int left = r[0];
+ int right = r[2];
+ int bot = r[1];
+ int top = r[3];
+ return new int[] {
+ left + random.nextInt(right - left + 1), bot + random.nextInt(top - bot + 1)
+ };
+ }
+}
diff --git a/src/main/java/g0401_0500/s0497_random_point_in_non_overlapping_rectangles/readme.md b/src/main/java/g0401_0500/s0497_random_point_in_non_overlapping_rectangles/readme.md
new file mode 100644
index 000000000..dfd450512
--- /dev/null
+++ b/src/main/java/g0401_0500/s0497_random_point_in_non_overlapping_rectangles/readme.md
@@ -0,0 +1,42 @@
+497\. Random Point in Non-overlapping Rectangles
+
+Medium
+
+You are given an array of non-overlapping axis-aligned rectangles `rects` where rects[i] = [ai, bi, xi, yi]
indicates that (ai, bi)
is the bottom-left corner point of the ith
rectangle and (xi, yi)
is the top-right corner point of the ith
rectangle. Design an algorithm to pick a random integer point inside the space covered by one of the given rectangles. A point on the perimeter of a rectangle is included in the space covered by the rectangle.
+
+Any integer point inside the space covered by one of the given rectangles should be equally likely to be returned.
+
+**Note** that an integer point is a point that has integer coordinates.
+
+Implement the `Solution` class:
+
+* `Solution(int[][] rects)` Initializes the object with the given rectangles `rects`.
+* `int[] pick()` Returns a random integer point `[u, v]` inside the space covered by one of the given rectangles.
+
+**Example 1:**
+
+
+
+**Input** ["Solution", "pick", "pick", "pick", "pick", "pick"] [[[[-2, -2, 1, 1], [2, 2, 4, 6]]], [], [], [], [], []]
+
+**Output:** [null, [1, -2], [1, -1], [-1, -2], [-2, -2], [0, 0]]
+
+**Explanation:**
+
+ Solution solution = new Solution([[-2, -2, 1, 1], [2, 2, 4, 6]]);
+ solution.pick(); // return [1, -2]
+ solution.pick(); // return [1, -1]
+ solution.pick(); // return [-1, -2]
+ solution.pick(); // return [-2, -2]
+ solution.pick(); // return [0, 0]
+
+**Constraints:**
+
+* `1 <= rects.length <= 100`
+* `rects[i].length == 4`
+* -109 <= ai < xi <= 109
+* -109 <= bi < yi <= 109
+* xi - ai <= 2000
+* yi - bi <= 2000
+* All the rectangles do not overlap.
+* At most 104
calls will be made to `pick`.
\ No newline at end of file
diff --git a/src/test/java/g0401_0500/s0492_construct_the_rectangle/SolutionTest.java b/src/test/java/g0401_0500/s0492_construct_the_rectangle/SolutionTest.java
new file mode 100644
index 000000000..41be42121
--- /dev/null
+++ b/src/test/java/g0401_0500/s0492_construct_the_rectangle/SolutionTest.java
@@ -0,0 +1,23 @@
+package g0401_0500.s0492_construct_the_rectangle;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void constructRectangle() {
+ assertThat(new Solution().constructRectangle(4), equalTo(new int[] {2, 2}));
+ }
+
+ @Test
+ void constructRectangle2() {
+ assertThat(new Solution().constructRectangle(37), equalTo(new int[] {37, 1}));
+ }
+
+ @Test
+ void constructRectangle3() {
+ assertThat(new Solution().constructRectangle(122122), equalTo(new int[] {427, 286}));
+ }
+}
diff --git a/src/test/java/g0401_0500/s0493_reverse_pairs/SolutionTest.java b/src/test/java/g0401_0500/s0493_reverse_pairs/SolutionTest.java
new file mode 100644
index 000000000..2f20a9289
--- /dev/null
+++ b/src/test/java/g0401_0500/s0493_reverse_pairs/SolutionTest.java
@@ -0,0 +1,18 @@
+package g0401_0500.s0493_reverse_pairs;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void reversePairs() {
+ assertThat(new Solution().reversePairs(new int[] {1, 3, 2, 3, 1}), equalTo(2));
+ }
+
+ @Test
+ void reversePairs2() {
+ assertThat(new Solution().reversePairs(new int[] {2, 4, 3, 5, 1}), equalTo(3));
+ }
+}
diff --git a/src/test/java/g0401_0500/s0495_teemo_attacking/SolutionTest.java b/src/test/java/g0401_0500/s0495_teemo_attacking/SolutionTest.java
new file mode 100644
index 000000000..4999a0af9
--- /dev/null
+++ b/src/test/java/g0401_0500/s0495_teemo_attacking/SolutionTest.java
@@ -0,0 +1,18 @@
+package g0401_0500.s0495_teemo_attacking;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void findPoisonedDuration() {
+ assertThat(new Solution().findPoisonedDuration(new int[] {1, 4}, 2), equalTo(4));
+ }
+
+ @Test
+ void findPoisonedDuration2() {
+ assertThat(new Solution().findPoisonedDuration(new int[] {1, 2}, 2), equalTo(3));
+ }
+}
diff --git a/src/test/java/g0401_0500/s0496_next_greater_element_i/SolutionTest.java b/src/test/java/g0401_0500/s0496_next_greater_element_i/SolutionTest.java
new file mode 100644
index 000000000..d4097fa6d
--- /dev/null
+++ b/src/test/java/g0401_0500/s0496_next_greater_element_i/SolutionTest.java
@@ -0,0 +1,22 @@
+package g0401_0500.s0496_next_greater_element_i;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void nextGreaterElement() {
+ assertThat(
+ new Solution().nextGreaterElement(new int[] {4, 1, 2}, new int[] {1, 3, 4, 2}),
+ equalTo(new int[] {-1, 3, -1}));
+ }
+
+ @Test
+ void nextGreaterElement2() {
+ assertThat(
+ new Solution().nextGreaterElement(new int[] {2, 4}, new int[] {1, 2, 3, 4}),
+ equalTo(new int[] {3, -1}));
+ }
+}
diff --git a/src/test/java/g0401_0500/s0497_random_point_in_non_overlapping_rectangles/SolutionTest.java b/src/test/java/g0401_0500/s0497_random_point_in_non_overlapping_rectangles/SolutionTest.java
new file mode 100644
index 000000000..bf75651df
--- /dev/null
+++ b/src/test/java/g0401_0500/s0497_random_point_in_non_overlapping_rectangles/SolutionTest.java
@@ -0,0 +1,20 @@
+package g0401_0500.s0497_random_point_in_non_overlapping_rectangles;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com_github_leetcode.CommonUtils;
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void solutionTest() {
+ Solution solution = new Solution(new int[][] {{-2, -2, 1, 1}, {2, 2, 4, 6}});
+ CommonUtils.printArray(solution.pick());
+ CommonUtils.printArray(solution.pick());
+ CommonUtils.printArray(solution.pick());
+ CommonUtils.printArray(solution.pick());
+ CommonUtils.printArray(solution.pick());
+ assertThat(true, equalTo(true));
+ }
+}