Algorithm intermediate learning 3

Keywords: Algorithm

1, Fibonacci formula (matrix method, fast power)

/**
 * @Author: Gao Yubo
 * @Date: 2021/11/27 20:47
 */
public class Fibonacci {
    public static void main(String[] args) {
        System.out.println(getFibonacci1(20));
        System.out.println(getFibonacci2(20));
    }

    public static int getFibonacci1(int N) {
        if (N == 1) {
            return 1;
        }
        if (N == 2) {
            return 1;
        }
        return getFibonacci1(N - 1) + getFibonacci1(N - 2);
    }

    /**
     * Fibonacci formula
     * The linear algebraic method is used for calculation
     */
    public static int getFibonacci2(int N) {
        if (N < 0) {
            return -1;
        }
        if (N == 1 || N == 2) {
            return 1;
        }
        //Get the base matrix of fibonacci
        int[][] base = {{1, 1}, {1, 0}};
        //Calculate the n-2 power of base
        int[][] res = matrixPower(base, N - 2);
        return res[0][0] + res[1][0];
    }

    //Matrix power
    public static int[][] matrixPower(int[][] base, int p) {
        //Identity matrix
        int[][] resMatrix = new int[base.length][base[0].length];
        for (int i = 0; i < base.length; i++) {
            resMatrix[i][i] = 1;
        }
        int[][] temp = base;
        //Counting 
        for (; p != 0; p >>= 1) {
            if ((p & 1) != 0) {
                resMatrix = muliMatrix(resMatrix, temp);
            }
            temp = muliMatrix(temp, temp);
        }
        return resMatrix;
    }
    //Computing matrix multiplication
    public static int[][] muliMatrix(int[][] temp, int[][] temp1) {
        int [][] res = new int[temp.length][temp1[0].length];
        for (int i = 0 ; i < temp.length; i++){
            for (int j = 0 ; j < temp1[0].length; j++){
                for (int k = 0; k < temp1.length; k++){
                    res[i][j] += temp[i][k] * temp1[k][j];
                }
            }
        }
        return res;
    }
}

2, I can't spell a triangle

On the hazy prairie, Xiao Hong picked up n sticks. The length of the i-th stick is I. Xiao Hong is very happy now. I want to choose three sticks to form a beautiful triangle. But Xiao Ming wants to tease Xiao Hong and remove some sticks, so that Xiao Hong can't form a triangle by choosing three sticks at will.
How many sticks should Xiao Ming remove at least?
Given N, return at least how many roots are removed?

/**
 * @Author: Gao Yubo
 * @Date: 2021/11/27 21:58
 */
public class DeleteWood {
    //Make sure the rest are Fibonacci numbers and you can't spell a triangle
    public static int minDelete(int m) {
        int fiboCount = getFiboCount(m);
        return m-fiboCount;
    }
    /**
     * Calculate the number of Fibonacci numbers in the [1-N] number
     */
    public static int getFiboCount(int N){
        int index1 = 1;
        int index2 = 2;
        int res = 2;
        while (index1 + index2 <= N){
            index1 += index2;
            index2 = index1 - index2;
            res++;
        }
        return res;
    }

    public static void main(String[] args) {
        int test = 8;
        System.out.println(minDelete(test));
    }
}

3, 01 Backpack

Niuniu is going to take part in the spring outing organized by the school. Before departure, Niuniu is going to put some snacks into his backpack. Niuniu's backpack has a capacity of w. Niuniu's family has n bags of snacks, and the volume of the I bag of snacks is v[i]. Niuniu wants to know how many kinds of snacks he has when the total volume does not exceed the backpack capacity (a total volume of 0 is also a method).

/**
 * @Author: Gao Yubo
 * @Date: 2021/11/27 22:12
 */
public class Bag01Problem {
    public static void main(String[] args) {
        int[] arr = { 4, 3, 2,5,3,5,8,2,3,4,58};
        int w = 8;
        int[][] ints = new int[arr.length][9];
        for (int i = 0 ; i < ints.length ; i++){
            Arrays.fill(ints[i],-1);
        }
        System.out.println(func4(arr, w,0));
        System.out.println(func5(arr, w));
    }
    public static int func4(int[] v,int weight,int index){
        if (weight < 0){
            return 0;
        }
        if (weight == 0){
            return 1;
        }
        if (index == v.length-1){
            return weight - v[index] >=0?2:1;
        }
        int s = func4(v,weight-v[index],index+1);
        int u = func4(v,weight,index+1);
        return s + u;
    }
    public static int func5(int[]v,int weight){
        int[][] dp  = new int[v.length][weight + 1];
        for (int i = 0; i < v.length; i++){
            dp[i][0] = 1;
        }
        for (int i = 0; i <= weight; i++){
            dp[v.length-1][i] = i - v[v.length-1] >=0?2:1;
        }
        for (int i = v.length-2; i >=0; i--){
            for (int j = 0; j <= weight; j++){
                dp[i][j] = j-v[i] < 0?dp[i+1][j]:dp[i+1][j-v[i]]+dp[i+1][j];
            }
        }
        return dp[0][weight];
    }
}

4, Print directory level

Give you an array arr of string type, for example: String [] arr = {"B \ CST", "d \", "a \ D \ e", "a \ B \ C"}; You draw the directory structure contained in these paths. The subdirectories are directly listed under the parent directory and two spaces to the right than the parent directory, like this:

a
b
c

​ d

​ e

b

​ cst

d
Those at the same level shall be arranged in alphabetical order and shall not be disordered.

/**
 * @Author: Gao Yubo
 * @Date: 2021/11/28 22:17
 * Give you an array arr of string type, for example: String [] arr = {"B \ \ CST", "d \ \", "a \ \ D \ \ e", "a \ \ B \ \ C"};
 * You draw the directory structure contained in these paths, and the subdirectories are directly listed under the parent directory and two spaces to the right than the parent directory
 */
public class PrintCatalogue {
    public static void main(String[] args) {
        String[] arr = { "b\\cst", "d\\", "a\\d\\e", "a\\b\\c" };
        print(arr);
    }
    static class Node{
        public String name;
        //Using sequential map, you can print in order
        public TreeMap<String ,Node> nextMap;
        public Node(String name){
            this.name = name;
            nextMap = new TreeMap<>();
        }
    }
    /**
     * Prefix tree mode
     * Each letter corresponds to a node. If the to be added is in the next of the current letter, it will be placed in the next. If not, it will be created
     */
    public static void print(String[] strings){
        Node head = generateFolderTree(strings);
        printTree(head,0);
    }

    private static Node getPrefixTree(String[] strings) {
        Node head = new Node("");
        Node cur = head;
        for (String str: strings){
            String[] letters = getLetters(str);
            //Update cur back to head
            cur = head;
            for (String letter: letters){
                if (!cur.nextMap.containsKey(letter)) {
                    cur.nextMap.put(letter,new Node(letter));
                }
                cur = cur.nextMap.get(letter);
            }
        }
        return head;
    }
    public static Node generateFolderTree(String[] folderPaths) {
        Node head = new Node("");
        for (String foldPath : folderPaths) {
            String[] paths = foldPath.split("\\\\");
            Node cur = head;
            for (int i = 0; i < paths.length; i++) {
                if (!cur.nextMap.containsKey(paths[i])) {
                    cur.nextMap.put(paths[i], new Node(paths[i]));
                }
                cur = cur.nextMap.get(paths[i]);
            }
        }
        return head;
    }
    public static void printTree(Node head, int level) {
        if (level != 0){
            System.out.println(getSpace(level)+head.name);
        }
        for (Node node: head.nextMap.values()){
            printTree(node,level+1);
        }
    }
    //Obtain different numbers of spaces according to the number of layers of the tree. There are no spaces in 1 layer and 2 spaces in 2 layers
    public static String getSpace(int level){
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 1; i < level;i++){
            stringBuilder.append("  ");
        }
        return stringBuilder.toString();
    }
    //Set "a \ \ B \ \ C" = > [a, B, C]
    public static String[] getLetters(String str){
        return str.split("\\\\");
    }
}

5, Convert bidirectional linked list (binary tree template)

The two-way linked list node structure is the same as the binary tree node structure, if you think last is left and next is next.
Given the head node of a search binary tree, please convert it into an ordered two-way linked list and return the head node of the linked list.

/**
 * @Author: Gao Yubo
 * @Date: 2021/11/28 22:55
 * The two-way linked list node structure is the same as the binary tree node structure, if you think last is left and next is next.
 * Given the head node of a search binary tree, please convert it into an ordered two-way linked list and return the chain
 * The header node of the table.
 */
public class ConvertDoubleList {
    public static void main(String[] args) {
        Node head = new Node(5);
        head.left = new Node(2);
        head.right = new Node(9);
        head.left.left = new Node(1);
        head.left.right = new Node(3);
        head.left.right.right = new Node(4);
        head.right.left = new Node(7);
        head.right.right = new Node(10);
        head.left.left = new Node(1);
        head.right.left.left = new Node(6);
        head.right.left.right = new Node(8);
        Node newHead = getDoubleLinkedList(head);
        printDoubleLinkedList(newHead);
    }
    public static void printDoubleLinkedList(Node head) {
        System.out.print("Double Linked List: ");
        Node end = null;
        while (head != null) {
            System.out.print(head.value + " ");
            end = head;
            head = head.right;
        }
        System.out.print("| ");
        while (end != null) {
            System.out.print(end.value + " ");
            end = end.left;
        }
        System.out.println();
    }
    public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int data) {
            this.value = data;
        }
    }
    static class Info{
        public Node head;
        public Node last;

        public Info(Node head, Node last) {
            this.head = head;
            this.last = last;
        }
    }
    public static Node getDoubleLinkedList(Node searchHead){
        Info info = f(searchHead);
        return info.head;
    }
    public static Info f(Node node){
        if (node == null){
            return new Info(null,null);
        }
        Info leftInfo = f(node.left);
        Info rightInfo = f(node.right);
        //connect
        if (leftInfo.last != null){
            leftInfo.last.right = node;
            node.left = leftInfo.last;
        }
        if (rightInfo.head != null){
            rightInfo.head.left = node;
            node.right = rightInfo.head;
        }
        Node head = leftInfo.head==null?node:leftInfo.head;
        Node last = rightInfo.last==null?node:rightInfo.last;
        return new Info(head,last);
    }
}

6, Given an integer matrix, returns the maximum cumulative sum of submatrixes.

/**
 * @Author: Gao Yubo
 * @Date: 2021/11/28 23:37
 * Maximum sum of submatrix
 */
public class MaxChildMatrixSum {
    public static void main(String[] args) {
        int[][] matrix = { { -90, 48, 78 }, { 64, -40, 64 }, { -81, -7, 66 } };
        System.out.println(getMaxMatrixSum(matrix));
    }
    /**
     * Add the lower row of the matrix to the upper row, and calculate the cumulative sum of the subarray
     */
    public static int getMaxMatrixSum(int[][] matrix){
        if(matrix == null || matrix.length == 0){
            return 0;
        }
        //Accumulate the upper layers of the matrix to facilitate the summation of subarrays, -- "change the summation of the matrix into the summation of one-dimensional arrays
        int[] sumMatrixArray = null;
        int cur = 0;
        int max = Integer.MIN_VALUE;
        for (int i = 0 ; i < matrix.length; i++){
            sumMatrixArray = new int[matrix[0].length];
            for (int j = i; j < matrix.length; j++){
                //Use maximum subarray and
                cur = 0;
                for (int k = 0 ; k < matrix[0].length;k++){
                    //accumulation
                    sumMatrixArray[k] += matrix[j][k];
                    cur += sumMatrixArray[k];
                    max = Math.max(max,cur);
                    cur = Math.max(0,cur);
                }
            }
        }
        return max;
    }
}

Posted by giba on Sat, 04 Dec 2021 14:34:33 -0800