计挑-国赛-Java-题5
测试用例1:
5
P1->P3
P2->P4
P4->P1
P3->P5
P1
输出1:
P2
3
测试用例2:
8
P3->P5
P5->P2
P4->P3
P2->P6
P1->P7
P6->P8
P8->P1
P6
输出2:
P4
5
没做出来,但是事后慢慢做出来了,所以是不熟练
很明显这是一个复合数据结构结构的设计题目
样子很像是组合出一条链表,但是涉及到几个问题:
- 拼接链表节点的时候,查找链表节点的问题,需要知道节点是否已经存在,存在了还要能获取到才能接
- 链表序列的排序问题,拼接过程中每个节点的索引号都是随时变化的,而且链表本身也不支持索引号访问以及根据节点查找索引
那么 - 首先至少要有一个索引map,给每个节点新增一个索引号属性并维护,同时能够根据给出的字段名获取,那毫无疑问肯定是map合适
- 其次光能够获取索引号还不够,还要保存并获取节点本身,所以再来一个map
题外话,我觉得这里两个map可能是冗余了,但是按照目前的思路是必要的,除非换个思路
最后是打印头节点,我觉得我这里的处理并不优雅,遍历索引map找索引号为1
一开始是打算用一个变量维护头节点的,但是发现这样做似乎并不能保证正确性
以下是本人代码,复合了两个map和单向链表:
import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class Main { /** * key是字符,value是索引位置,主要用来排序,用来给链表排序并查询每个节点的排序位置 */ private static final Map<String, Integer> findNodeIndexMap = new HashMap<>(); /** * key是字符,value是节点,用来方便获取节点,因为链表每次获取节点都需要遍历 * 用来检查节点是否存在 */ private static final Map<String, Node> findNodeMap = new HashMap<>(); /** * 链表节点定义 */ static class Node { Node next = null; String name; public Node(String name) { this.name = name; } } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); sc.nextLine();// 吞掉一行空行 for (int i = 0; i < n - 1; i++) { String str = sc.nextLine(); String pre = str.substring(0, 2); String next = str.substring(4); if (findNodeMap.get(pre) == null) { /* 后节点空不空都要新建一个前节点 */ Node newPreNode = new Node(pre); findNodeMap.put(pre,newPreNode); findNodeIndexMap.put(pre,1); if (findNodeMap.get(next) == null) { /* 如果两个节点都不存在,就新建这两个节点并加入到map中 */ Node nodeNext = new Node(next); newPreNode.next = nodeNext; findNodeIndexMap.put(nodeNext.name, 2); findNodeMap.put(nodeNext.name, nodeNext); } else { /* 前节点空但是后节点不空,就要在前面追加一个新节点 */ newPreNode.next = findNodeMap.get(next); addIndex(newPreNode); } } else { /* 前节点存在,修改后节点指针,不存在就new一个 */ Node node = findNodeMap.get(pre); Node nextNode; if (findNodeIndexMap.get(next) != null) nextNode = findNodeMap.get(next); else { nextNode = new Node(next); findNodeMap.put(next, nextNode); findNodeIndexMap.put(next, 1); } node.next = nextNode; addIndex(node); } } // 遍历map找到索引为1的头节点 findNodeIndexMap.forEach((k,v)-> { if(v==1) System.out.println(k); }); /* 查找指定节点的索引号 */ String get = sc.nextLine(); System.out.println(findNodeIndexMap.get(get)); } /** * 追加更新node后面所有的节点索引 */ private static void addIndex(Node node) { int startIndex = findNodeIndexMap.get(node.name); while (node.next != null) { node = node.next;// 更新链表节点指针 findNodeIndexMap.put(node.name, ++startIndex);// 更新节点的索引号 } } }
本文作者:YaosGHC
本文链接:https://www.cnblogs.com/yaocy/p/17017038.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步