Long Luo's Life Notes

每一天都是奇迹

By Long Luo

252. 会议室 253. 会议室 II
2402. 会议室 III

252. 会议室

暴力

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static boolean canAttendMeetings_bf(int[][] intervals) {
int len = intervals.length;
if (len <= 1) {
return true;
}

for (int i = 0; i < len; i++) {
for (int j = i + 1; j < len; j++) {
int[] m1 = intervals[i];
int[] m2 = intervals[j];

if (!(m1[1] <= m2[0] || m1[0] >= m2[1])) {
return false;
}
}
}

return true;
}

排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static boolean canAttendMeetings(int[][] intervals) {
if (intervals == null || intervals.length <= 1) {
return true;
}

Arrays.sort(intervals, (a, b) -> {
if (a[0] == b[0]) {
return a[1] - b[1];
}
return a[0] - b[0];
});

for (int i = 1; i < intervals.length; i++) {
if (intervals[i][0] < intervals[i - 1][1]) {
return false;
}
}

return true;
}
阅读全文 »

By Long Luo

This article is the solution 4 Approaches: Two Pointers, Sorting, Priority Queue and Binary Search of Problem 658. Find K Closest Elements.

Here shows 4 Approaches to slove this problem: Two Pointers, Sorting, Priority Queue and Binary Search with Two Pointers.

Two Pointers

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
// TP time: O(n) space: O(1)
public static List<Integer> findClosestElements(int[] arr, int k, int x) {
List<Integer> ans = new ArrayList<>();
int len = arr.length;
int targetPos = -1;
int delta = Integer.MAX_VALUE;
for (int i = 0; i < len; i++) {
if (Math.abs(arr[i] - x) < delta) {
delta = Math.abs(arr[i] - x);
targetPos = i;
}
}

ans.add(arr[targetPos]);
k--;

int left = targetPos - 1;
int right = targetPos + 1;
while (k > 0) {
if (left >= 0 && right < len && Math.abs(arr[left] - x) <= Math.abs(arr[right] - x)) {
ans.add(arr[left]);
left--;
k--;
} else if (left >= 0 && right < len && Math.abs(arr[left] - x) > Math.abs(arr[right] - x)) {
ans.add(arr[right]);
right++;
k--;
} else if (left >= 0 && right == len) {
ans.add(arr[left]);
left--;
k--;
} else if (left < 0 && right < len) {
ans.add(arr[right]);
right++;
k--;
}
}

Collections.sort(ans);

return ans;
}

Analysis

  • Time Complexity: \(O(n + k \log k)\).
  • Space Complexity: \(O(n)\).
阅读全文 »

By Long Luo

This article is the solution 3 Approaches: Brute Force, Stack, Slow Fast Pointers with Animation of Problem 19. Remove Nth Node From End of List .

Here shows 3 Approaches to slove this problem: Brute Force, Stack, Slow Fast Pointers.

Brute Froce

It’s easy to think of the way that we traverse the linked list first, from the head node to the end node, to get the length of the linked list \(L\).

Then we traverse the linked list from the head node again. When the \(L-n+1\) th node is traversed, it is the node we need to delete.

We can traverse \(L-n+1\) nodes starting from the dummy node. When traversing to the \(L-n+1\)th node, its next node is the node we need to delete, so we only need to modify the pointer once to complete the deletion operation.

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
public static ListNode removeNthFromEnd(ListNode head, int n) {
if (head.next == null && n == 1) {
return null;
}

List<ListNode> nodeList = new ArrayList<>();
ListNode pNode = head;
int size = 0;
while (pNode != null) {
nodeList.add(pNode);
size++;
pNode = pNode.next;
}

if (n == size) {
return head.next;
} else if (n == 1) {
pNode = nodeList.get(size - 2);
pNode.next = null;
} else {
pNode = nodeList.get(size - n - 1);
pNode.next = pNode.next.next;
}

return head;
}

Analysis

  • Time Complexity: \(O(n)\)
  • Space Complexity: \(O(n)\)
阅读全文 »

By Long Luo

This article is the solution From Brute Force to DP to Two Pointers with Detail Explaination of Problem 42. Trapping Rain Water .

Intuition

Trapping Rain Water

It’s like Leetcode 11. Container With Most Water , we can consider the black block as a wall, the blue block as water. Given an array, each element represents the height of the wall from left to right, find out how many units of water can be held.

The solution can be refered 2 Approaches: BF and Two Pointers with Image Explaination .

1. Brute Force

It’s easy to use the brute force approach. The time complexity is \(O(max^n)\) , so it will TLE.

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
// Row time: O(max * n) space: O(1)
// TLE
public static int trap_row(int[] height) {
if (height == null || height.length <= 2) {
return 0;
}

int ans = 0;
int len = height.length;
int maxHeight = 0;

for (int x : height) {
maxHeight = Math.max(maxHeight, x);
}

for (int i = 1; i <= maxHeight; i++) {
boolean flag = false;
int water = 0;
for (int j = 0; j < len; j++) {
if (flag && height[j] < i) {
water++;
}

if (height[j] >= i) {
ans += water;
water = 0;
flag = true;
}
}
}

return ans;
}

Analysis

  • Time Complexity: \(O(max^n)\)
  • Space Complexity: \(O(1)\)
阅读全文 »

By Long Luo

大学时学通信专业课程 计算机网络1 时,需要学习 TCP/IP 协议族 2 。在学习网络层的路由协议时, \(\textit{Dijkstra}\) 3 算法是必须要掌握的。不过读书时,对这个算法是懵懵懂懂的,当时是死记硬背记住的,并没有理解其原理,过了一段时间之后就完全忘记了。如今在 2022 年我重新学习 搜索算法4 时,已经彻底理解 \(\textit{Dijkstra}\) 算法了。更确切的说,如果我们掌握了其原理,我们也可以重新发明 \(\textit{Dijkstra}\) 算法,就让我们从一个自驾游例子开始吧!

到达目的地哪条路径最快?

假期时,我们想从深圳自驾去上海,怎么去呢?打开地图软件,地图会给你规划好几条路线,在找到这些路线的背后就用到了 \(\textit{A Star}\)5 算法 或者 \(\textit{Dijkstra}\) 算法,它们都属于 最短路径算法6 。这个例子解释 用来\(\textit{Dijkstra}\) 算法并不是特别好,但方便大家理解。

假如回到那个 2G 时代,没有导航软件只有一张地图,大家会怎么做呢?

我们可能要根据到高速和城市之间里程来计算,比如北上赣州,经南昌、杭州到上海和经福建、温州、宁波再到上海哪个更快,不同城市之间高速路况情况,每段之间耗时多长,最后得到了一条路线。虽然大部分人并不知道 \(\textit{Dijkstra}\) 算法,但并不妨碍我们天生就会用 \(\textit{Dijkstra}\) 算法,所以我们把这个思考过程写下来,实际上就是 \(\textit{Dijkstra}\) 算法。

让我们重新一步一步来发现 \(\textit{Dijkstra}\) 算法吧!

从 BFS 开始

由于找合适的国内城市路线图和制图太花时间,刚好维基上的 Breadth-first search algorithm7 的页面上就提供了德国国内城市地图的例子,这里就借用下,如下图所示:

Germany Map
图1. 德国城市地图

如果我们从 法兰克福(Frankfurt) 出发,很容易得到到达各个城市的最快方式,如下图所示:

Germany BFS

以下面这个动图为例,我们来看看 \(\textit{BFS}\) 是如何做的?

bfs

从上图可以看出,\(\textit{BFS}\) 的运行过程可以描述如下:

  1. 首先选择一个顶点作为起始结点,并将其染成蓝色,其余未访问结点为黑色
  2. 将起始结点放入队列中;
  3. 从队列首部选出一个顶点,并找出所有与之邻接的结点,将找到的邻接结点放入队列尾部,将已访问过结点涂成蓝色,没访问过的结点是黑色。如果顶点的颜色是蓝色,表示已经发现并且放入了队列,如果顶点的颜色是黑色,表示还未访问;
  4. 按照同样的方法处理队列中的下一个结点,直到所有节点都访问完毕。

伪代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
procedure BFS(G, source) is
let Q be a queue
label source as explored

Q.enqueue(source)

while Q is not empty do
v := Q.dequeue()

if v is the goal then
return v

for all edges from v to w in G.adjacentEdges(v) do
if w is not labeled as explored then
label w as explored
w.parent := v
Q.enqueue(w)
阅读全文 »
0%