7月算法训练------第三十天(拓扑排序)解题报告

7月算法训练------第三十天(拓扑排序)解题报告

题目类型:拓扑排序
题目难度:中等

第一题、207. 课程表

  1. 题目链接:207. 课程表
  2. 思路分析:
  • 根据拓扑排序的思想,先构建一个关系矩阵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
    这一题还是有一定难度的。
  1. 代码:
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. 到达目的地的方案数

  1. 题目链接:1976. 到达目的地的方案数
  2. 思路分析:
    这一题先占个位置,是在有点做吐了。

剑指offer

题目类型:双指针
难度:简单

第三题、剑指 Offer 18. 删除链表的节点

  1. 题目链接:剑指 Offer 18. 删除链表的节点

  2. 思路分析:
    当链表头节点的值与val相等时,就把head.next返回。
    定义一个临时变量,遍历整个链表,如果有某个节点的值和这个链表的值相等,则将这个链表节点删去。思路很简单。

  3. 代码:

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个节点

  1. 题目链接:剑指 Offer 22. 链表中倒数第k个节点
  2. 思路分析:
    这一题也非常简单,思路就是遍历一遍链表,这一遍的目的是知道链表中有几个节点。
    知道有几个节点之后,也就知道了需要在第len-k次循环之后返回结果。
    然后,循环len-k次,就将链表返回。
  3. 代码:
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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值