while (l <= mid && r <= right) {
if (items[l].val > items[r].val) {
// l > r, means move r to l, so insert r data to temp,
// and add rightcount , ex 5 2 => 2 5, but rightCount should++
rightCount++;
temp[tempIdx++] = items[r++];
} else {
// if l < r, it is sorted, ex: 2 5,
// cal count result(count[l index] += rightCnt),
// insert l data to temp
count[items[l].idx] += rightCount;
temp[tempIdx++] = items[l++];
}
}
็ฌฌไบๅ while ๅฐฑ่ท ็ฌฌไธๅ while else ๅ ถๅฏฆๅ งๅฎนไธๆจฃ ๏ผ ๅ ็บๆฏ l <= mid)
while (l <= mid) { // insert remained l data, and cal count, (insert l data means cal result!)
count[items[l].idx] += rightCount;
temp[tempIdx++] = items[l++];
}
ex 5 2 .=> 2, 5 ไนๅพ, ้ๅฉไธ 5, ๆไปฅๅก 5 ๅฐ temp[1] .( while l <= mid
while (l <= mid) { // insert remained l data, and cal count, (insert l data means cal result!)
count[items[l].idx] += rightCount;
temp[tempIdx++] = items[l++];
}
while (r <= right) { // insert remained r data
temp[tempIdx++] = items[r++];
}
// finally put sorted temp data to items
for (int p = 0; p < temp.length; p++) {
items[left + p] = temp[p];
}
class Solution {
private class Item {
int val;
int idx;
public Item(int val, int idx) {
this.val = val;
this.idx = idx; // for count use
}
}
public List<Integer> countSmaller(int[] nums) {
int n = nums.length;
int[] count = new int[n];
Item[] items = new Item[n];
for (int i = 0; i < n; i++) {
items[i] = new Item(nums[i], i);
}
mergeSort(items, 0, n - 1, count);
List<Integer> result = new ArrayList<>();
for (int cnt : count) {
result.add(cnt);
}
return result;
}
private void mergeSort(Item[] items, int left, int right, int[] count) {
if (left >= right) return;
int mid = (right + left) >> 1;
mergeSort(items, left, mid, count);
mergeSort(items, mid + 1, right, count);
merge(items, left, mid, right, count);
}
private void merge(Item[] items, int left, int mid, int right, int[] count) {
Item[] temp = new Item[right - left + 1];
int tempIdx = 0;
int l = left;
int r = mid + 1;
int rightCount = 0;
while (l <= mid && r <= right) {
if (items[l].val > items[r].val) {
// l > r, means move r to l, so insert r data to temp,
// and add rightcount , ex 5 2 => 2 5, but rightCount should++
rightCount++;
temp[tempIdx++] = items[r++];
} else {
// if l < r, it is sorted, ex: 2 5,
// cal count result(count[l index] += rightCnt),
// insert l data to temp
count[items[l].idx] += rightCount;
temp[tempIdx++] = items[l++];
}
}
while (l <= mid) { // insert remained l data, and cal count, (insert l data means cal result!)
count[items[l].idx] += rightCount;
temp[tempIdx++] = items[l++];
}
while (r <= right) { // insert remained r data
temp[tempIdx++] = items[r++];
}
// finally put sorted temp data to items
for (int p = 0; p < temp.length; p++) {
items[left + p] = temp[p];
}
}
}