【2016去哪儿网笔试题】找出输入中有几个死锁

(题目大致意思)
寻找输入中有几个死锁,首先输入总共有多少条数据。然后一行输入的信息中第一列代表数据id,第二列代表正在占用的资源id(如果有多个,则用逗号分割,没有则为空格),第三列代表申请占用的资源id(如果有多个,则用逗号分割,没有则为空格)。每列之间用制表符分割。判断其中有多少个死锁。
输入为了避免分不清制表符和空格,我在原题的基础上加上了[制表符]和[空格 ]来区分制表符(tab键)和空格(space键)
7
125[制表符]1001,1002[制表符]1003
126[制表符]1003[制表符]1004
127[制表符][空格][制表符][空格]           
128[制表符][空格]1005
129[制表符]1004[制表符]1002
130[制表符]1006[制表符][空格]
131[制表符]1007[制表符]1005
输出
1
思路分析:
1006——>null
1007——>1005
1001
        \
          > 1003——>1004
        /                          |
1002 <—————— |
以上存在一个环,所以只有一个死锁
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Scanner;
/**
 * 思路:
 * 1、读取解析所有输入
 * 2、依次将这些数值以链表的形式连接起来
 * 3、然后遍历(一步两步看是否重合的形式)判断是否有环
 * 4、如果有环,将环中的节点放到Set中,最后看有多少个不同的环,就有多少个死锁现象
 */
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int len = in.nextInt();
        in.nextLine();
        // 用来存储值和其相应节点
        HashMap<Integer,ListNode> map = new HashMap<Integer,ListNode>();
        // 遍历所有输入
        for(int i=0;i<len;i++){
            // 读取输入的数据
            String str = in.nextLine();
            String[] newstr = parserString(str);
            // 正在占用的资源
            ArrayList<Integer> left = new ArrayList<Integer>();
            // 申请占用的资源
            ArrayList<Integer> right = new ArrayList<Integer>();
            // 如果正在占用资源中有值,不为null,也不为空格
            if(newstr[1]!=null&&!newstr[1].equals(" ")){
                left = parserToint(newstr[1]);
            }
            else{
                continue;
            }
            // 如果申请占用资源中有值,不为null,也不为空格
            if(newstr[2]!=null&&!newstr[2].equals(" ")){
                right = parserToint(newstr[2]);
            }
            else{
                continue;
            }
            // 将正在占用的资源与申请占用的资源,链接起来
            for(int j=0;j<right.size();j++){
                ListNode nodeRight = null;
                if(!map.containsKey(right.get(j))){
                    nodeRight = new ListNode(right.get(j));
                    nodeRight.next = null;
                    map.put(right.get(j), nodeRight);
                }
                else{
                    nodeRight = map.get(right.get(j));
                }
                for(int x=0;x<left.size();x++){
                    ListNode nodeLeft = null;
                    if(!map.containsKey(left.get(x))){
                        nodeLeft = new ListNode(left.get(x));
                    }
                    else{
                        nodeLeft = map.get(left.get(x));
                    }
                    nodeLeft.next = nodeRight;
                    map.put(left.get(x), nodeLeft);
                }
            }
        }
        // set用来存储有循环的节点集合,set中有多少个这样的集合,就有多少次死锁发生
        HashSet<HashSet<ListNode>> set = new HashSet<HashSet<ListNode>>();
        for(int key : map.keySet()){
            if(returnLoopSet(map.get(key))!=null){
                set.add(returnLoopSet(map.get(key)));
            }
        }
        System.out.println(set.size());
        in.close();
    }
    // 以制表符为分割符来分割输入的一组数据
    public static String[] parserString(String str){
        return str.split("\t");
    }
    // 以逗号为分割符,来解析其中的数值
    public static ArrayList<Integer> parserToint(String str){
        String[] strArray = str.split(",");
        ArrayList<Integer> list = new ArrayList<Integer>(); 
        for(int i=0;i<strArray.length;i++){
            list.add(Integer.valueOf(strArray[i]));
        }
        return list;
    }
    // 找到有环的所有节点的集合
    public static HashSet<ListNode> returnLoopSet(ListNode node){
        ListNode node1 = node;
        ListNode node2 = node;
        HashSet<ListNode> hashSet = new HashSet<ListNode>();
        // 通过一步两步遍历的方式来判断是否有环
        while(node1!=null&&node2!=null&&node1.next!=null&&node2.next.next!=null){
            node1 = node1.next;
            hashSet.add(node1);
            node2 = node2.next.next;
            if(node1.equals(node2)){
                return hashSet;
            }
        }
        return null;
    }
}
// 自定义链表类
class ListNode{
    int value;
    ListNode next;
    public ListNode(int value){
        this.value = value;
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值