zoukankan      html  css  js  c++  java
  • 算法辅助代码

    本部分提供一些常用的代码模板,尽量节约算法笔试的时间

    目录

    1 输入输出流

    2 定义链表

     2.1 单向链表

     2.2 双向链表

    3 创建链表

     3.1 创建单向链表

     3.2 创建双向链表

    4 定义创建树并遍历

    5 利用字符串创建树,并建立对应关系和parent指向

    注:广泛采用static是为了方便main方法调用

    1 输入输出流

    public static void main(String[] args) throws Exception{
        //采用输入流接收输入
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        //将第一次换行符前的所以输入以空格分开并保存成字符串的形式
        String[] strings = bf.readLine().split(" ");
        //将某些参数转换成整数
        int n = Integer.parseInt(strings[0]);
    
        /***
         * 中间业务代码
         */
    
        //采用输出流可以提高执行速度
        StringBuilder builder = new StringBuilder();
        //这里是将链表转换成字符串形式再输出要比直接输出链表速度快
        while(head!=null){
            builder.append(head.val).append(" ");
            head = head.next;
        }
        //输出字符串
        System.out.print(builder.toString());
    }

    2 定义链表

    单向链:

    private static class Node{
        public int val;
        public Node next;
    
        public Node(int val){
            this.val = val;
        }
    }

    双向链表:

    //定义出双向节点
    private static class Node{
        private int val;
        private Node last;
        private Node next;
        public Node(int val){
            this.val = val;
        }
    }

    3 创建链表

    创建单向链表

    //通过传入的字符串和字符串的长度来创建链表
    private static Node createLinkedList(String[] strings, int n){
        //先创建一个头结点
        Node head = new Node(Integer.parseInt(strings[0]));
        //创建其余节点
        Node cur = head;
        for (int i = 1; i < n; i++) {
            cur.next = new Node(Integer.parseInt(strings[i]));
            cur = cur.next;
        }
        cur.next = null;
        return head;
    }

    创建双向链表

    //创建双向链表
    private static Node createDoubleList(String[] strings,int n){
        Node head = new Node(Integer.parseInt(strings[0]));
        Node node = head;
        for (int i=1;i<n;i++){
            Node newNode = new Node(Integer.parseInt(strings[i]));
            node.next = newNode;
            newNode.last = node;
            node = newNode;
        }
        return head;
    }

    注:参数n可要可不要是随机调整的;在创建链表的时候有时使用虚拟头结点会比较好处理,但虚拟头结点不应该在创建创建链表的时候创建,而应该在具体业务代码处创建。

    4 定义创建树并遍历

    这里采用的是牛客网上给出创建树的规则:

    定义树结点

    //定义树结点
    private static class TreeNode{
        TreeNode left;
        TreeNode right;
        int val;
    
        public TreeNode(int val) {
            this.val = val;
            left = null;
            right = null;
        }
    }

    创建树

    //创建树
    private static void createTree(TreeNode node, int[][] triple) {
        int val = node.val;
        int left_val = triple[val][0];
        int right_val = triple[val][1];
    
        if(left_val!=0)
        {
            TreeNode lNode = new TreeNode(left_val);
            node.left = lNode;
            createTree(lNode,triple);
        }
        if(right_val!=0)
        {
            TreeNode rNode = new TreeNode(right_val);
            node.right = rNode;
            createTree(rNode,triple);
        }
    }
    //将字符传转换为整数数组
    private static int[] getIntArray(String str) {
        String[] temp = str.split(" ");
        int[] result = new int[temp.length];
        for(int i=0; i<temp.length; i++)
        {
            result[i] = Integer.parseInt(temp[i]);
        }
        return result;
    }

    main方法中的使用:

    public static void main(String[] args) throws Exception{
        //采用输入流接收输入
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        //将第一次换行符前的所以输入以空格分开并保存成字符串的形式,根据题意这里保不保存都无所谓的,反正递归创建没有用的
        String[] temp = bf.readLine().split(" ");
        int nodeNum = Integer.parseInt(temp[0]);//节点数目
        int firstNumber = Integer.parseInt(temp[1]); //第一个节点
        int[][] triple = new int[nodeNum+1][2];
        //将节点间的信息保存到一个三元组中triple
        for(int i=0; i<nodeNum; i++) {
            String[] str = bf.readLine().split(" ");
            int temp1 = Integer.parseInt(str[0]); //取第一个数为索引
            triple[temp1][0] = Integer.parseInt(str[1]); //记录左孩子
            triple[temp1][1] = Integer.parseInt(str[2]); //记录右孩子
        }
        
        TreeNode root = new TreeNode(firstNumber);//创建头节点
        //创建树
        createTree(root, triple);
        
        //业务代码
        
        //作为结果的输出流
        StringBuilder sb = new StringBuilder();
    
    }

     另一种创建树的规则:

     

     main方法:sum是额外输入的,这里注意下即可,对于创建树影响不大

    public static void main(String[] args) throws Exception{
        //采用输入流接收输入
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        //将第一次换行符前的所以输入以空格分开并保存成字符串的形式,根据题意这里保不保存都无所谓的,反正递归创建没有用的
        String[] temp = bf.readLine().split(" ");
        //下面这两个变量其实没有意义了
        int nodeNum = Integer.parseInt(temp[0]);//节点数目
        int firstNumber = Integer.parseInt(temp[1]); //第一个节点
        //创建树,这句和下面的sum位置交换后就会报错,不知道为什么
        TreeNode root = buildTree(bf);
       int sum = Integer.parseInt(bf.readLine());
    }

    创建树:

    public static TreeNode buildTree(BufferedReader bufr)throws IOException {
        int left ,right,data;
        String[] datas = bufr.readLine().split(" ");
        data = Integer.valueOf(datas[3]);
        right = Integer.valueOf(datas[2]);
        left = Integer.valueOf(datas[1]);
        TreeNode head = new TreeNode(data);
        if(left!=0){
            head.left = buildTree(bufr);
        }
        if(right!=0){
            head.right = buildTree(bufr);
        }
        return head;
    }

    把树输出:

    public static void main(String[] args) throws Exception{
        //树的遍历的业务代码
        //前序遍历
        preOrder(treeNode,sb);
        //因为在前序遍历时会多添加一个空格,因此这里最后一个空格不能读取
        System.out.println(sb.substring(0,sb.length()-1));
        //清空
        sb.delete(0,sb.length());
        //中序遍历
        innerOrder(treeNode,sb);
        System.out.println(sb.substring(0,sb.length()-1));
        sb.delete(0,sb.length());
        reviewOrder(treeNode,sb);
        System.out.println(sb.substring(0,sb.length()-1));
    }
    
    //前序遍历
    private static StringBuilder  preOrder(TreeNode treeNode,StringBuilder sb){
        if (treeNode==null){
            return null;
        }
        sb.append(treeNode.val+" ");
        preOrder(treeNode.left,sb);
        preOrder(treeNode.right,sb);
        return sb;
    }

    上面是前序中序后序遍历,只给出前序遍历的代码,其他的是类似的,注意如何使用字符流。

    直观打印出二叉树

    //直观打印出二叉树
    public static void printTree(TreeNode head) {
        System.out.println("Binary Tree:");
        printInOrder(head, 0, "H", 17);
        System.out.println();
    }
    public static void printInOrder(TreeNode head, int height, String to, int len) {
        if (head == null) {
            return;
        }
        printInOrder(head.right, height + 1, "v", len);
        String val = to + head.val + to;
        int lenM = val.length();
        int lenL = (len - lenM) / 2;
        int lenR = len - lenM - lenL;
        val = getSpace(lenL) + val + getSpace(lenR);
        System.out.println(getSpace(height * len) + val);
        printInOrder(head.left, height + 1, "^", len);
    }
    public static String getSpace(int num) {
        String space = " ";
        StringBuffer buf = new StringBuffer("");
        for (int i = 0; i < num; i++) {
            buf.append(space);
        }
        return buf.toString();
    }

    5 利用字符串创建树,并建立对应关系和parent指向

    //定义树结点
    private static class TreeNode{
        TreeNode left;
        TreeNode right;
        TreeNode parent;
        int val;
    
        public TreeNode(int val) {
            this.val = val;
            left = null;
            right = null;
            parent = null;
        }
    
        public TreeNode(int val, TreeNode parent) {
            this.val = val;
            this.parent = parent;
        }
    }
    //根据传入的数组创建二叉树,并存成map的形式,方便通过值找到对应的节点
    private static TreeNode createBinaryTree(String[] lines, int n, int rootVal, Map<Integer, TreeNode> map) {
        for (int i = 0; i < n; i++) {
            String[] strArr = lines[i].split(" ");
            int curVal = Integer.valueOf(strArr[0]);
            int leftVal = Integer.valueOf(strArr[1]);
            int rightVal = Integer.valueOf(strArr[2]);
            //建立起map映射,put和putIfAbsent的区别:
            //使用put方法添加键值对,如果map集合中没有该key对应的值,则直接添加,并返回null,如果已经存在对应的值,则会覆盖旧值,value为新的值。
            //使用putIfAbsent方法添加键值对,如果map集合中没有该key对应的值,则直接添加,并返回null,如果已经存在对应的值,则依旧为原来的值。
            map.putIfAbsent(curVal, new TreeNode(curVal));
            if (leftVal != 0) {
                map.put(leftVal, new TreeNode(leftVal, map.get(curVal)));
                map.get(curVal).left = map.get(leftVal);
            }
            if (rightVal != 0) {
                map.put(rightVal, new TreeNode(rightVal, map.get(curVal)));
                map.get(curVal).right = map.get(rightVal);
            }
        }
        return map.get(rootVal);
    }

    主方法中的创建

    public static void main(String[] args) throws Exception{
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        //接收到前两个参数
        String[] numStrArr = in.readLine().split(" ");
        int n = Integer.valueOf(numStrArr[0]);
        int rootVal = Integer.valueOf(numStrArr[1]);
        //依次读取每行数值
        String[] lines = new String[n];
        for (int i = 0; i < n; i++) {
            lines[i] = in.readLine();
        }
        //创建二叉树
        Map<Integer, TreeNode> map = new HashMap<>();
        TreeNode root = createBinaryTree(lines, n, rootVal, map);
        //获得给定值的节点
        TreeNode node = map.get(Integer.valueOf(in.readLine()));
    }

    这里创建的规则仍然是按照4中的,只不过这里用上了第一行的信息

    0

  • 相关阅读:
    Fiddler 只看指定URL请求
    WTM框之—调整默认的删除方法
    WTM框之—调整grid的每页显示行数
    WTM框之—数据列表上添加按钮的学习记录
    Armbian欢迎信息系统状态脚本
    Shell中的${xxx%% *}字符串分割方法
    强制SSH使用密钥认证禁止密码登录
    Linux开机自动挂载外接存储
    mysql实现name姓名多个相同的数据只取一条
    git 常用命令备忘录
  • 原文地址:https://www.cnblogs.com/youngao/p/12089505.html
Copyright © 2011-2022 走看看