5/25/2023 新建了这篇笔记(呜呜呜不知道什么时候才能开始写下一个字)
6/13/2023 完成了Union-Find(并查集)的视频观看。
6/22/2023 完成了第一次大作业Percolation。6/20就提交了92分的不考虑backwash的版本但是直到今天才完成100分的版本…backwash并不好想但是也不难想,还是自己太菜了。
6/23/2023 今天看完了Analysis of Algorithm的前两个视频……(Analysis of Algorithms Introduction和Mathematical Models)。由于微积分没学好并看不太懂后面的算法分析部分。后面似乎用到了Euler-Maclaurin公式?哭死。估计这部分要等重学微积分后重新回顾了……不过该说不说,内容还是很精彩的……
6/26/2023 今天完成了Analysis of Algorithm剩下的部分。这部分简单提到了一些Theory of Algorithm的内容,介绍了upper bound和lower bound等一系列内容。最后的memory usage的笔记如下:
boolean 1 byte 1 char 2 int 4 float 4 long 8 double 8
char[] 2N + 24 (24 for some overhead)
int[] 4N + 24
double[] 8N + 24
char[][] ~2MN
int[][] ~4MN
double[][] ~8MN
Object overhead. 16 bytes. Reference. 8 bytes.
Padding: Each object uses a multiple of 8 bytes.
注意Object的内部有数组的时候需要加一个reference的memory 8 bytes。另外要注意Object的大小需要是8的整数倍。
最后:Big Theta classify algorithms. Big Oh develop upper bound. Big Omega develop lower bounds.
6/27/2023 今天看完了Module 2的Stacks这个视频。里面基本上讲了用LinkedList和Array两种方法实现Stack。
6/29/2023 完成了Module 2 Stacks and Queues的视频部分。
7/23/2023 (这几天好累啊呜呜)完成了Week2 Stacks and Queues的Assignment。这个Assignment是关于手动实现一个Deque和一个RandomizedQueue的。这个作业虽然没那么难,但是也有不少需要注意的点。首先,对于操作的时间和内存都有一定的要求。对于Deque,要注意List上只有一个Node时执行删除的处理。另外,要注意删除节点后同时移除该节点的引用,从而避免loitering。
对于RandomizedQueue,需要注意resize arraym,同样也要让不再使用的array指向null。这个作业还涉及到了Iterator的写法。
最后,作业有个bonus涉及到了Reservoir Sampling。我把这个算法的描述和代码贴在下面(来自ChatGPT):
Create a reservoir array of size k and populate it with the first k items of the input.
For each item from k+1 through n:
- Generate a random number j between 0 and the index i of the current item (inclusive).
- If j is less than k, replace the jth element in the reservoir array with the ith item from the input.
This program randomly selects
k
items from an arraystream
of sizen
.
public class ReservoirSampling {
// A function to randomly select k items from stream[0..n-1]
static void selectKItems(int stream[], int n, int k)
{
int i; // index for elements in stream[]
// reservoir[] is the output array. Initialize it with
// first k elements from stream[]
int reservoir[] = new int[k];
for (i = 0; i < k; i++)
reservoir[i] = stream[i];
Random r = new Random();
// Iterate from the (k+1)th element to nth element
for (; i < n; i++)
{
// Pick a random index from 0 to i.
int j = r.nextInt(i + 1);
// If the randomly picked index is smaller than k,
// then replace the element present at the index
// with new element from stream
if(j < k)
reservoir[j] = stream[i];
}
}
9/1/2023 截至今天的进度是看完了Elementray Sort中的Insertion Sort. Selection Sort是找最小的插(交换)到序列的位置中,而Insertion Sort是与当前元素的前一个元素进行比较并且交换。
9/4/2023 完成了Week2的所有内容。觉得非常有意思的内容是Convex Hull(闭包)。利用极坐标系的角度排序,以及特定的检测两条线段是顺逆时针关系的ccw算法,可以很轻松地计算出数个点的Convex Hull。同时排序算法的效率是Convex Hull算法的效率的主要因素。真喜欢这门课举的实际生活的例子啊。可以让学生很容易明白这些算法究竟有什么用,能够解决什么实际生活中的问题。
1/3/2024 啊怎么新一年了呜呜呜呜呜上完班以后好累,感觉看视频的效率都好差有点心不在焉。到今天为止,看到了Week3 Mergesort的Comparators。(中间还看了一两次并没有在这里记录)
这一个视频讲了Java中的Comparable和Comparator的概念。我自己的理解是Comparable就是赋予类一个排序的顺序,而Comparator是创建出来使得一堆类的实例可以按照不同的属性来排序的“比较器”。Comparator的其中一个应用就是作为第二个参数传入Arrays.sort()这个函数,使得排序按照我们自定义的顺序来执行的。另外,视频中还提到了一种Comparator的写法,即nested class -- 把它写在我们自定义的类中。这样下次想要调用的时候,可以直接用类名调用:
public class Student
{
public static final Comparator<Student> BY_NAME = new ByName();
public static final Comparator<Student> BY_SECTION = new BySection();
private final String name;
private final int section;
...
private static class ByName implements Comparator<Student>
{
public int compare(Student v, Student w)
{ return v.name.compareTo(w.name); }
}
private static class BySection implements Comparator<Student>
{
public int compare(Student v, Student w)
{ return v.section - w.section; }
}
调用时:
Arrays.sort(a, Student.BY_NAME);
Arrays.sort(a, Student.BY_SECTION);
实现自己的sort函数时,也可以使用Comparator:(太累了我要休息去了……)
public static void sort(Object[] a, Comparator comparator)
{
int N = a.length;
for (int i = 0; i < N; ++i)
for (int j = i; j > 0; && less(comparator, a[j], a[j - 1]); j--)
exch(a, j, j - 1);
}
private static boolean less(Comparator c, Object v, Object w)
{ return c.compare(v, w) < 0; }
private static void exch(Object[] a, int i, int j)
{ Object swap = a[i]; a[i] = a[j]; a[j] = swap; }