Used to summarize personal problems encountered in the brush algorithm, while recording some specific algorithm templates

The dictionary tree

It is usually used to determine whether there is a corresponding string in the dictionary or to speed up the search efficiency.

Template:

class TrieNode {
	boolean isWord;							
	TrieNode[] children = new TrieNode[26];		

	public TrieNode(){}}class TrieNode {		
	boolean isWord;								
	TrieNode[] children = new TrieNode[26];		
}

class Trie {

    TrieNode root;      

    public Trie() {
        root = new TrieNode();      
    }

    public void insert(String word) {
        TrieNode cur = root;                        
        for (int i = 0; i < word.length(); i++) {	
            int c = word.charAt(i) - 'a';           
            if (cur.children[c] == null) {
                cur.children[c] = new TrieNode();
            }
            cur = cur.children[c];
        }
        cur.isWord = true;                          
    }
public boolean search(String word) {
        TrieNode cur = root;

        for (int i = 0; i < word.length(); i++) {
            int c = word.charAt(i) - 'a';
            if (cur.children[c] == null) {
                return false;
            }
            cur = cur.children[c];
        }
        return cur.isWord;
    }
    public boolean startsWith(String word) {
        TrieNode cur = root;

        for (int i = 0; i < word.length(); i++) {
            int c = word.charAt(i) - 'a';
            if (cur.children[c] == null) {
                return false;
            }
            cur = cur.children[c];
        }
        return true;
    }
Copy the code

Search method variant:

public boolean search(String word) {
	return match(word, root, 0);
}

———— = node.children[c]; /* macth (); /* macth (); =null) // (start = I for(I)
public boolean match(String word, TrieNode node, int start){		// This is the template parameter
    if(start == word.length()){								
        return node.isWord;					/ / (u)
    }

    int c = word.charAt(start) - 'a';
    returnnode.children[c] ! =null && match(word, node.children[c], start + 1);
Copy the code

Recommended articles :blog.csdn.net/m0_46202073…

The prefix and

Check the sum of intervals frequently

Template:


int n = nums.length;
// Prefix and array
int[] preSum = new int[n + 1];
preSum[0] = 0;
for (int i = 0; i < n; i++)
    preSum[i + 1] = preSum[i] + nums[i];

Copy the code

Recommended article: zhuanlan.zhihu.com/p/107778275

Difference array

Frequently incrementing or subtracting the value of an array as a whole

Template:

int[] diff = new int[nums.length];

// Create a difference array

diff[0] = nums[0];

for (int i = 1; i < nums.length; i++) {

diff[i] = nums[i] - nums[i - 1];

}
Copy the code

The diff difference array can be used to derive the original numS, the code logic is as follows:

int[] res = new int[diff.length];
// Build the result array from the difference array
res[0] = diff[0];
for (int i = 1; i < diff.length; i++) {
    res[i] = res[i - 1] + diff[i];
}
Copy the code

If you want to add 3 to all the elements in nums[I..j], just add diff[I] += 3, and then diff[j+1] -= 3.

Recommended article: labuladong. Gitbook. IO/algo/mu – lu -…

The sliding window

There are several ways to ask questions:

  • Give two strings, one long and one short, and ask if the shorter exists in the long string. For example:
  • Find the shortest substring that is long. The substring must cover all the short characters
  • All the positions in which the short anagram appears in the long
  • .
  • Given a string or array, ask if the substring or subarray of the string meets certain conditions, for example:
  • The largest string containing less than K distinct characters
  • The oldest string in which all characters occur only once
  • .

In addition, there are some other questions, but the same is that this kind of problem is inseparable from the main array (main array) and the subarray (subarray) relationship, the time complexity is usually O(n), space complexity is often constant.

public int slidingWindowTemplate(String[] a, ...) {
    // Determine the validity of input parameters
    if (...) {
        ...
    }

    // Apply a hash to record the number of specific elements in the window
    // This is represented as an array. You can also consider other data structures
    int[] hash = newint[...] ;// Preprocess (save), usually by changing hash.// l represents the left pointer
    // count specifies the current condition
    // result is used to store results
    int l = 0, count = ... , result = ... ;for (int r = 0; r < A.length; ++r) {
        // Update the number of new elements in the hash
        hash[A[r]]--;

        // Change the conditional value according to the window change result
        if (hash[A[r]] == ...) {
            count++;
        }

        // If the current condition is not met, move the left pointer until the condition is met
        while(count > K || ...) {...if(...). { count--; } hash[A[l]]++; l++; }// Update the result
        results = ...
    }

    return results;
}
Copy the code

Recommended article: zhuanlan.zhihu.com/p/69818691

A topological sort

What is topological sort?

Topological sorting: The process of extracting a topological sequence of a given graph from all its edges. A topological sequence is a sequence satisfying the context of directed edges in the graph. Any starting point of directed edges must appear earlier than the end point in the sequence. If there are rings in the graph, the topological sequence cannot be extracted. So an important application of topological sorting is to determine the existence of loops in a given directed graph.

Purpose: Topological sort is to find the node with 0 degree of entry in the graph, and only points to the node with 0 degree of entry

Therefore, it can be concluded that the node with an outdegree of 0 can be obtained by reverse topology sorting.

Process: first find the node with an access degree of 0, and then eliminate it, so that the input degree of the next node corresponding to it is -1, and then cycle.

/ / sample [[1, 2], [3], [3], []] indicating that node 0 degrees to 1 to 3, 1, 2, node node 2 to 3
public List<Integer> TopologicalSorting(int[][] nums) {
    int size = nums.length;
    // Record the output degree of each node
    List<List<Integer>> list = new ArrayList<>();
    // Record the input of each node
    int[] inCount = new int[size];

    for (int i = 0; i < size; i++) { List<Integer> tmp =new ArrayList();
        for (int j = 0; j < nums[i].length; j++) { inCount[nums[i][j]] ++; tmp.add(nums[i][j]); } list.add(tmp); } Deque<Integer> deque =new LinkedList<>();
    for (int i = 0; i < size; i++) {// Add a node whose degree is 0
        if (inCount[i] == 0) { deque.add(i); }}while(! deque.isEmpty()) { int top = deque.removeFirst();for (int node : list.get(top)) {
            inCount[node]--;
            if (inCount[node] == 0) {
                deque.addLast(node);
            }
        }
    }
    List<Integer> res = new ArrayList<>();
    for (int i = 0; i < size; i++) {if (inCount[i] == 0) { res.add(i); }}return res;
}
Copy the code

leetcode-cn.com/problems/fi…

Check and set

For example, if A is related to B and B is related to C, then A and C are related

template

class UnionFind {
    // The number of unrelated items
    private int count;
    // The final result is displayed as a two-level multi-fork tree structure
    private int[] parent;

    public UnionFind(int count) {
        this.count = count;
        parent = new int[count];
        for(int i = 0; i < count; i++) { parent[i] = i; } } public intfind(int x) {
        int root = x;
        while(root ! = parent[root]) { root = parent[root]; }// Adjust to the unified root node
        while(x ! = parent[x]) { int p = x; parent[x] = root; x = parent[p]; }return root;
    }
    / / merge
    public void union(int x,int y) {
        int xRoot = find(x);
        int yRoot = find(y);
        if(xRoot == yRoot) return;
        parent[xRoot] = yRoot;
        count--;
    }
    public int getCount() {
        returncount; }}Copy the code

Sample entry: 547. Number of provinces

Advanced example: longest continuous sequence

tips

Loops in arrays – redundant traps

For example, [1,3,6,2,4] Starts from node 0 and the step is 1. The step is 3. The step is 4 How is such a relationship represented in Java? (The step size in the array can also be negative)

Wrong way:

while(! visited[index]){// index current position, size array length
    index = (nums[index] + index + size) % size;
    visited[index] = true;
}
Copy the code

In Java, when the step size is -9, the current coordinate is 2, and size is 3, the index value is -1, and the subscript is out of bounds. In c the index value is 2.

 while(! visited[index]) { visited[index] =true;
    index = (((nums[index] + index) % size) + size) % size;
 }
Copy the code

The value ranges from 1 to 9

char c = (char)(count + 48)
Copy the code

Generate range from known random number, get new random number range

Rand7 () generates random numbers 1-7. So you can go through

(rand7() -1) * 7 + rand7() generates random numbers in the range 1-49Copy the code

Principle: rand7() -1) * 7 produces 0, 7, 14… The discrete value of, plus the value rand7 used to fill the middle blank.