7月算法训练------第三十天(拓扑排序)解题报告
题目类型:拓扑排序
题目难度:中等
第一题、207. 课程表
- 题目链接:207. 课程表
- 思路分析:
- 根据拓扑排序的思想,先构建一个关系矩阵
rela
和一个入度数组inter
,声明好之后,对关系矩阵和入读数组进行初始化,由先修课程指向后修课程构建有向图:
rela[i][j] = 1
时,表示由第i
个节点指向第j
个节点;当为0
时,表示这两个节点之间没有关系。
inter[i] = 0
时,表示没有节点指向第i
个节点;不为0
时表示,有inter[i]
个节点指向第i个节点。 - 对这两个初始化完成之后,就用一个队列dq来存储当前入度为0的节点;根据拓扑排序的思想,我们需要将这个节点删去,并将它的指向都删去,表现在本题就是,将入度为0的节点从
dq
队头的元素删去,将它加入到HashSet
中, 同时将这个节点指向关系删除,表现为将inter[j]
入度值减一(j
表示第i
个节点指向的第j
个节点),即将第j
个节点的入度减一。 - 最后,遍历一遍整个
HashSet
,如果没有包含从0~numCourses-1
的所有课程,就返回false
;如果都包含就返回true
。
这一题还是有一定难度的。
- 代码:
class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
int[] inter = new int[numCourses];
int[][] rela = new int[numCourses][numCourses];
Deque<Integer> dq = new ArrayDeque();
Set<Integer> set = new HashSet();
for(int i = 0; i < prerequisites.length; i++){
rela[prerequisites[i][1]][prerequisites[i][0]] = 1;
inter[prerequisites[i][0]]++;
}
for(int i = 0; i < numCourses; i++){
if(inter[i] == 0){
dq.addLast(i);
}
}
while(!dq.isEmpty()){
int t = dq.pollFirst();
set.add(t);
for(int j = 0; j < numCourses; j++){
if(rela[t][j] == 1){
inter[j]--;
if(inter[j] == 0){
set.add(j);
dq.addLast(j);
}
}
}
}
for(int i = 0; i < numCourses; i++){
if(!set.contains(i)){
return false;
}
}
return true;
}
}
第二题、1976. 到达目的地的方案数
- 题目链接:1976. 到达目的地的方案数
- 思路分析:
这一题先占个位置,是在有点做吐了。
剑指offer
题目类型:双指针
难度:简单
第三题、剑指 Offer 18. 删除链表的节点
-
题目链接:剑指 Offer 18. 删除链表的节点
-
思路分析:
当链表头节点的值与val
相等时,就把head.next
返回。
定义一个临时变量,遍历整个链表,如果有某个节点的值和这个链表的值相等,则将这个链表节点删去。思路很简单。 -
代码:
class Solution {
public ListNode deleteNode(ListNode head, int val) {
if(head.val == val) return head.next;
ListNode temp = head;
while(temp.next != null){
if(temp.next.val == val){
temp.next = temp.next.next;
}else{
temp = temp.next;
}
}
return head;
}
}
第四题、剑指 Offer 22. 链表中倒数第k个节点
- 题目链接:剑指 Offer 22. 链表中倒数第k个节点
- 思路分析:
这一题也非常简单,思路就是遍历一遍链表,这一遍的目的是知道链表中有几个节点。
知道有几个节点之后,也就知道了需要在第len-k
次循环之后返回结果。
然后,循环len-k
次,就将链表返回。 - 代码:
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
int len = 1;
ListNode temp = head;
while(temp != null){
len++;
temp = temp.next;
}
for(int i = 1; i < len - k; i++){
head = head.next;
}
return head;
}
}