-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathCountOfSmallerNumberThenSelf.java
More file actions
134 lines (87 loc) · 3.21 KB
/
CountOfSmallerNumberThenSelf.java
File metadata and controls
134 lines (87 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
Count of smaller numbers after self
Problem Description
Given an array of integers A, find and return new integer array B.
Array B has the property where B[i] is the number of smaller elements to the right of A[i].
Problem Constraints
1 <= length of the array <= 100000
1 <= A[i] <= 109
Input Format
The only argument given is the integer array A.
Output Format
Return the new integer array B.
Example Input
A = [1, 5, 4, 2, 1]
Example Output
[0, 3, 2, 1, 0]
Example Explanation
Number of smaller elements to the right of 1 are 0.
Number of smaller elements to the right of 5 are 3 (4, 2, 1).
Number of smaller elements to the right of 4 are 2 (2, 1).
Number of smaller elements to the right of 2 are 1 (1).
Number of smaller elements to the right of 1 are 0.
*/
/*
Solution Approach
We can do this by using two loops and find the answer for each index in the array.
Time complexity for this will be O(N2). This will fail for large test case.
Approach 1
Use the idea of the merge sort at the time of merging two arrays.
When higher index element is less than the lower index element, it represents that the higher index element is smaller than all the elements after that lower index because the left part is already sorted.
Hence add up to all the elements after the lower index element for the required count.
Approach 2
For optimized solution we can use data compression and bit(fenwick tree).
We will sort the given data in other auxilary array and then compressed the values staring from 1.
Now for the original array, we loop through it back, first find the answer for that element using query in bit and then add the element in the bit.
Store these value in another array and return that.
*/
public class Solution {
class NumberIndex {
int number;
int index;
NumberIndex(int number, int index) {
this.number = number;
this.index = index;
}
NumberIndex(NumberIndex another) {
this.number = another.number;
this.index = another.index;
}
}
public int[] solve(int[] nums) {
NumberIndex[] cnums = new NumberIndex[nums.length];
for (int i = 0; i < nums.length; i++) {
cnums[i] = new NumberIndex(nums[i], i);
}
int[] smaller = new int[nums.length];
cnums = sort(cnums, smaller);
return smaller;
}
private NumberIndex[] sort(NumberIndex[] nums, int[] smaller) {
int half = nums.length / 2;
if (half > 0) {
NumberIndex[] rightPart = new NumberIndex[nums.length - half];
NumberIndex[] leftPart = new NumberIndex[half];
for (int i = 0; i < leftPart.length; i++) {
leftPart[i] = new NumberIndex(nums[i]);
}
for (int i = 0; i < rightPart.length; i++) {
rightPart[i] = new NumberIndex(nums[half + i]);
}
NumberIndex[] left = sort(leftPart, smaller), right = sort(
rightPart, smaller);
int m = left.length, n = right.length, i = 0, j = 0;
while (i < m || j < n) {
if (j == n || i < m && left[i].number <= right[j].number) {
nums[i + j] = left[i];
smaller[left[i].index] += j;
i++;
} else {
nums[i + j] = right[j];
j++;
}
}
}
return nums;
}
}