您的位置:首页 > 其它

[LeetCode]--315. Count of Smaller Numbers After Self(Binary Search Tree && Merge Sort)

2016-08-16 20:07 435 查看

Problem

Problem_Link



Solutions

Binary Search Tree



So, see the code!

public class Solution {
class Node {
Node left, right;
int val, sum, dup = 1;
// "val" means the value of this node, "sum" represents the total number ofon its left bottom side.
public Node(int v, int s) {
val = v;
sum = s;
}
}
public List<Integer> countSmaller(int[] nums) {
Integer[] ans = new Integer[nums.length];
Node root = null;
for (int i = nums.length; i >= 0; i--) {
root = insert(nums[i], root, ans, i, 0);
}
return Arrays.asList(ans);
}
private Node insert(int num, Node node, Integer[] ans, int i, int preSum) {
if (node == null) {
node = new Node(num, 0);
} else if (node.val == num) {
node.dup++;
ans[i] = preSum + node.sum;
} else if (node.val > sum) {
node.sum++;
// preSum--attention
node.left = insert(num, num.left, ans, i, preSum);
} else {
// preSum + node.dup + node.sum
node.right = insert(num, num.right, ans, i, preSum + node.dup + node.sum);
}
return node;
}
}


Merge Sort Solution(Python)

Reference:https://discuss.leetcode.com/topic/31162/mergesort-solution

The smaller numbers on the right of a number are exactly those that jump from its right to its left during a stable sort. So I do mergesort with added tracking of those right-to-left jumps.

At first, I want to understand the Python Solution use the merge sort solution!

def countSmaller(self, nums):
def sort(enum):
half = len(enum) / 2
if half:
left, right = sort(enum[:half]), sort(enum[half:])
for i in range(len(enum))[::-1]:
if not right or left and left[-1][1] > right[-1][1]:
smaller[left[-1][0]] += len(right)
enum[i] = left.pop()
else:
enum[i] = right.pop()
return enum
smaller = [0] * len(nums)
sort(list(enumerate(nums)))
return smaller


Merge Sort Solution(Java)

Reference: https://discuss.leetcode.com/topic/31554/11ms-java-solution-using-merge-sort-with-explanation

The Merge Sort idea is follows!

Variables We Need

1.
left[]
and
right[]
, do the merge sort operation, supposed that
left[]
and
right[]
are already sorted.

2. rightcount is used to [record how many numbers from
right[]
.

3. count[left.length]: Because the
right[]
doesn’t need count to record this.

Variables We Do

1. Increase the rightcount by 1 when u move a number from
right[]
into the new sorted array.

2. Increase the count[index of number from the left[]] by the present value of rightcount when u move a number from
left[index]
into the new sorted array.

int[] count;
public List<Integer> countSmaller(int[] nums) {
List<Integer> res = new ArrayList<Integer>();

count = new int[nums.length];
int[] indexes = new int[nums.length];
for(int i = 0; i < nums.length; i++){
indexes[i] = i;
}
mergesort(nums, indexes, 0, nums.length - 1);
for(int i = 0; i < count.length; i++){
res.add(count[i]);
}
return res;
}
private void mergesort(int[] nums, int[] indexes, int start, int end){
if(end <= start){
return;
}
int mid = (start + end) / 2;
mergesort(nums, indexes, start, mid);
mergesort(nums, indexes, mid + 1, end);

merge(nums, indexes, start, end);
}
private void merge(int[] nums, int[] indexes, int start, int end){
int mid = (start + end) / 2;
int left_index = start;
int right_index = mid+1;
int rightcount = 0;
int[] new_indexes = new int[end - start + 1];

int sort_index = 0;
while(left_index <= mid && right_index <= end){
if(nums[indexes[right_index]] < nums[indexes[left_index]]){
new_indexes[sort_index] = indexes[right_index];
rightcount++;
right_index++;
}else{
new_indexes[sort_index] = indexes[left_index];
count[indexes[left_index]] += rightcount;
left_index++;
}
sort_index++;
}
while(left_index <= mid){
new_indexes[sort_index] = indexes[left_index];
count[indexes[left_index]] += rightcount;
left_index++;
sort_index++;
}
while(right_index <= end){
new_indexes[sort_index++] = indexes[right_index++];
}
for(int i = start; i <= end; i++){
indexes[i] = new_indexes[i - start];
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: