leetcode: Course Schedule II

整体思路很容易想到,就是从没有先修课的课程入手,逐渐找到所有课程的一个可能的顺序....

最初我用courseInfo来记录每门课程的先修课集合,通过while循环中每一次都扫描所有的courseInfo找出这一轮可以修的课程,但是超时;因为在比较差的条件下,这样的代价是n*n的...

那么不妨用courseInfo记录每门课是哪些课程的先修课,并用一个数组preNum记录每门课的先修课数量...那么我们只需要动态的维持一个stack/queue,保证其内都是可修的课程,通过对courseInfo中记录的后修课信息的修改(preNum),寻找新的可修课程并加入stack/queue。这样的代价实际上是n的。。。


public class Solution {
    public int[] findOrder(int numCourses, int[][] prerequisites) {
        List<HashSet<Integer>> courseInfo = new ArrayList<HashSet<Integer>>();
        int[] preNum=new int[numCourses];
        for( int i=0;i<numCourses;i++ )
        {
           courseInfo.add( new HashSet<Integer>() ); 
        }
        for( int[] pre:prerequisites )
        {
            if( !courseInfo.get(pre[1]).contains(pre[0]) )
        	{
        		courseInfo.get(pre[1]).add(pre[0]);
        		preNum[pre[0]]++;
        	}
        }
        int[] res= new int[numCourses];
        int count=0;
        Stack<Integer> stack=new Stack<Integer>();
        // Queue<Integer> queue = new LinkedList<Integer>();
        for( int i=0;i<numCourses;i++ )
        {
            if( preNum[i]==0 )
            {
                stack.push(i);
                // queue.add(i);
                res[count++]=i;
            }
        }
        while( !stack.isEmpty() )
        {
            int course=stack.pop();
            // int course=queue.poll();
            for( int co:courseInfo.get(course) )
            {
                preNum[co]--;
                if( preNum[co]==0 )
                {
                    stack.push(co);
                    // queue.offer(co);
                    res[count++]=co;
                }
            }
        }
        if( count==numCourses )
        {
            return res;
        }
        else
        {
            return new int[0];
        }

    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值