Angorithm4 Webinar #3
Cohost by Jiawei Wang 2021-10-29
1. Review ISC
Trade off
- In 1981s. Compiler technology didn’t develop well at that time.
- Simple Compiler, Complex Hardware vs. Complex Compiler, Simple Hardware
### Decode in x86: * Intel’s and AMD’s x86 implementations translate x86 instructions into programmer-invisible microoperations (simple instructions) in hardware * In fact, in most x86-64 machines today, what’s the processors do is that they take the complex instructions, they translate down, and save the translated form, so next time, when you get the same instruction, you don’t need to translate it again. You just take the simple micro-operations. * All high-performance processors’ underneath looks like RISC processors
2. Comparision Sort(I) - Merge Sort
i. Description
void Merge(int* A, int* L, int leftCount, int* R, int rightCount) {
int i, j, k;
= 0, j = 0, k = 0;
i
while (i < leftCount && j < rightCount)
{
if(R[j] < L[i]) A[k++] = R[j++];
else A[k++] = L[i++];
}
// last check
while (i < leftCount) A[k++] = L[i++];
while (j < rightCount) A[k++] = R[j++];
}
void MergeSort(int* A, int n) {
int mid, *L, *R;
if (n < 2) return;
= n / 2;
mid
= new int[mid];
L = new int[n - mid];
R
for(int i = 0; i < mid; i++) L[i] = A[i];
for(int j = mid; j < n; j++) R[j-mid] = A[j];
(L, mid);
MergeSort(R, n-mid);
MergeSort
(A, L, mid, R, n-mid);
Merge
delete [] R;
delete [] L;
}
5 2 6 1
| 1 2 5 6 |
| 2 5 | 1 6 |
| 5 | 2 | 6 | 1 |
ii. Analysis
T(N) = 2T(N/2) + O(N)
O(NlogN)
iii. Example (LeetCode 315)
LeetCode 315 Count Number of Smaller Numbers After Self
Input: [5,2,6,1] Output: [2,1,1,0]
class Solution {
public:
<int> countSmaller(vector<int>& nums) {
vectorfor (int i = 0; i < nums.size(); i++) {
int count = 0;
for (int j = i+1; j < nums.size(); j++) {
if (nums[j] < nums[i]) count++;
}
[i] = count;
nums}
return nums;
}
};
Divide and Conquer
[A A A A A B B B B B]
[A A A A A][B B B B B]
[X X X X]
using namespace::std;
class Solution {
<int> counts;
vectorpublic:
<int> countSmaller(vector<int>& nums) {
vectorint N = nums.size();
.resize(N);
counts
if (N == 0) return {};
<int> sortedNums = nums;
vector
(nums, sortedNums, 0, N-1);
helper
return counts;
}
private:
void helper(vector<int>& nums, vector<int>& sortedNums, int start, int end) {
if (start == end) return;
int mid = start + (end - start) / 2; // round down ((int) x / 2 <= (float) x / 2)
(nums, sortedNums, start, mid);
helper(nums, sortedNums, mid+1, end);
helper
for (int i = start; i <= mid; i++) {
auto iter = lower_bound(sortedNums.begin() + mid + 1, sortedNums.begin() + end + 1, nums[i]); // [mid+1, end+1)
[i] += iter - (sortedNums.begin() + mid + 1); // Ranking in [mid+1, end]
counts}
<int> temp(end - start + 1); // to store the merged vector from start to end
vector// sort(sortedNums.begin()+start, sortedNums.begin()+end+1);
int i = start, j = mid+1, p = 0;
while (i <= mid && j <= end) {
if (sortedNums[i] <= sortedNums[j]) {
[p] = sortedNums[i];
temp++;
i} else {
[p] = sortedNums[j];
temp++;
j}
++;
p}
while (i <= mid) {
[p] = sortedNums[i];
temp++;
i++;
p}
while (j <= end) {
[p] = sortedNums[j];
temp++;
j++;
p}
for (int i = 0; i < end-start+1; i++) {
[start+i] = temp[i];
sortedNums}
}
};
Runtime
5 2 6 1
| 1 2 5 6 | <- counts = [2, 1, 1, 0]
| 2 5 | 1 6 | <- counts = [1, 0, 1, 0]
| 5 | 2 | 6 | 1 | <- start == end return