• 算法题(java)


    1. 查找有效服务
      (凭记忆描叙)有一系列的服务,例如a1,a2,a3,…等,a1-a2表示a1依赖a2,如果服务a2出错,那么a1也就不正常了,假设a1-a2,a2-a3, a3出错,或导致a1,a2都不正常,但如果只是a1出错,不会影响a2.
      输入的第一行是依赖关系,第二行是出错的服务,以逗号隔开,例如:
      输入:
      a1-a2,a3-a4,a5-a6
      a2,a5

    输出(能正常运行的服务,按关系列表前后顺序)
    a3,a4,a6

    如果没有存活的服务,打印error

    算法分析:
    算法的关键点是要注意传递依赖关系,例如a1-a2,a2-a3这种。

    算法描叙:在出错列表中,选择第一个出错服务ai,查找依赖列表,将所有依赖ai的关系找出来,例如aj-ai,将ai设置为ERROR(flag),并把aj加入到出错列表,知道所有错误服务都已查询,将关系列表中存活的服务打印出来即可。

    package test;
    
    import java.util.Scanner;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Set;
    import java.util.HashSet;
    
    public class Main {
    	static final String flag = "error";
    	static class Relation{
    		String node;
    		String rNode;
    		public Relation(String node, String rNode) {
    			this.node = node;
    			this.rNode = rNode;
    		}
    	}
    	
    	public static void main(String[] args) {
    		Scanner sc = new Scanner(System.in);
    		String relations = sc.nextLine();
    		String errors = sc.nextLine();
    		sc.close();
    		long startTime = System.currentTimeMillis(); 
    		ArrayList<String> errList = new ArrayList<>();
    		Collections.addAll(errList, errors.split(","));
    		ArrayList<Relation> rList = new ArrayList<>();
    		for(String relation:relations.split(",")) {
    			String rStr[] = relation.split("-");
    			rList.add(new Relation(rStr[0], rStr[1]));
    		}
    		Set<String> checked = new HashSet<>();
    		for(int i=0; i<errList.size(); ++i) {
    			String errNode = errList.get(i);
    			if(checked.contains(errNode)) {
    				continue;
    			}
    			checked.add(errNode);
    			for(int j=0;j<rList.size();) {
    				Relation r = rList.get(j);
    				if(r.node.equals(errNode)) {
    					r.node = flag;
    					++j;
    				} else if(r.rNode.equals(errNode)){
    					if(!r.node.equals(flag)) {
    						errList.add(r.node);
    					}
    					rList.remove(j);
    				} else {
    					++j;
    				}
    			}
    		}
    		StringBuilder sb = new StringBuilder();
    		Set<String> exist = new HashSet<>();
    		for(int i=0;i<rList.size(); ++i) {
    			Relation r = rList.get(i);
    			if(!r.node.equals(flag)) {
    				addNode(r.node, exist, sb);
    			}
    			addNode(r.rNode, exist, sb);
    		}
    		System.out.println(sb.toString());
    		System.out.println("cost:" + (System.currentTimeMillis() - startTime));
    	}
    	
    	public static void addNode(String node, Set<String> exist, StringBuilder sb) {
    		if(!exist.contains(node)) {
    			sb.append(node);
    			sb.append(",");
    			exist.add(node);
    		}
    	}
    }
    
    • 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
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75

    注:我这没考虑结果为空的情况

    1. 度假天数
      (凭记忆描叙)某人打算去欧洲旅行,然后给定一个数组,表示某天可以去旅游的景点,例如,[1,2,1,2,3,7,2,1]:
      a[0] = 1
      a[1] = 2
      a[2] = 1
      a[3] = 2
      a[4] = 7
      a[5] = 2
      a[6] = 1
      我们可以看到,如果从第一天开始(序号为0),到第五天就可以看完所有景点,总共需要5天时间,但是如果从第三天开始,那么只需要三天就可以看完所有景点。

    输入,给定一个数组,值为1~200,
    输出,看完素有景点需要的最少天数(必须是连续的)

    算法描叙:用map来计算,前者表示景点的数,后者表示看过该景点的次数,并用count来记录已看过的景点个数,用指针begin表示起始的日期,当count=n(总共的景点个数)时,begin到i当前的索引天数就是满足要求的一个窗口,然后移动窗口,计数减一,查找下一个窗口:

    	static int findSortestDaily(int[] arr) {
    		Map<Integer, Integer> map = new HashMap<>();
    		for(int a:arr) {
    			map.put(a, 0);
    		}
    		int goal = map.size();
    		
    		int begin=0;
    		int count=0;
    		int min = goal;
    		for(int i=0;i<arr.length; ++i) {
    			int a = arr[i];
    			if(map.get(a) == 0) {
    				map.put(a, 1);
    				++count;
    				if(count == goal) {
    					while(count == goal) {
    						int b = arr[begin];
    						int tmp = map.get(b) -1;
    						map.put(b, tmp);
    						if(tmp == 0) {
    							--count;
    						}
    						++begin;
    					}
    					min = Math.min(min, i - begin + 2);
    				}
    			} else {
    				int tmp = map.get(a) + 1;
    				map.put(a, tmp);
    			}
    		}
    		
    		return min;
    	}
    
    • 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
    1. 打印所欲有效括号
      输入一个整数,打印出所有有效的括号组合,例如
      n=1, 输出
      ()
      n=2,输出:
      (()),()()

    算法简单,找到规律就行,不解释,直接上代码:

    	static ArrayList<String> getComp(int n) {
    		ArrayList<String> res = new ArrayList<>();
    		if(n < 1) {
    			return res;
    		}
    		if(n == 1) {
    			res.add("()");
    		} else if(n == 2) {
    			res.add("(())");
    			res.add("()()");
    		} else {
    			ArrayList<String> subs = getComp(n-1);
    			for(String sub: subs) {
    				res.add("(" + sub + ")");
    			}
    			Set<String> set = new HashSet<>();
    			for(String sub: subs) {
    				String tmp = "()" + sub;
    				if(!set.contains(tmp)) {
    					res.add(tmp);
    					set.add(tmp);
    				}
    				tmp = sub + "()";
    				if(!set.contains(tmp)) {
    					res.add(tmp);
    					set.add(tmp);
    				}
    			}
    			set.clear();
    			subs.clear();
    		}
    		return res;
    	}
    
    • 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
    1. 两数之和
      给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

    你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

    你可以按任意顺序返回答案。

    	static int[] fun(int[] nums, int target) {
    		int len=nums.length;
    		Map<Integer, Integer> map = new HashMap<>();
    		for(int i=0; i<len; i++) {
    			if(map.containsKey(nums[i])) {
    				int[] res = new int[2];
    				res[0] = map.get(nums[i]);
    				res[1] = i;
    				return res;
    			} else {
    				int diff = target - nums[i];
    				map.put(diff, i);
    			}
    		}
    		return new int[0];
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    【初阶与进阶C++详解】第十七篇:红黑树(插入+验证+查找)
    iceoryx之Roudi
    weak的自动置空
    雷神轮胎携手JBL 演绎科技降噪、感受非凡音悦
    【HEC-RAS】2D模型初步介绍(4)-2D与1D相结合
    flutter plugins插件【二】【FlutterAssetsGenerator】
    MES管理系统和ERP系统在生产制造管理中的应用
    智能制造时代下,MES管理系统需要解决哪些问题
    位运算详细介绍
    【数据结构与算法】第五篇:B树
  • 原文地址:https://blog.csdn.net/dingpwen/article/details/126130106