Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

310 Commits
 
 
 
 
 
 

Repository files navigation

Leetcode

Array and Linked List

Sequence

General Method :

​ Two pointers (sliding window):

  • Two onward pointers (sliding window)
  • One onward pointer + One backward pointer

General Implementation Steps:

  1. Use two pointers: start and end to represent a window.
  2. Move end to find a valid window.
  3. When a valid window is found, move start to find a smaller window.

Template :

int findSubstring(string s){
        int[] map = new int[256];
        int counter; // check whether the substring is valid
        int begin=0, end=0; //two pointers, one point to tail and one  head
        int d; //the length of substring

        for() { /* initialize the hash map here */ }

        while(end<s.size()){

            if(map[s[end++]]-- ?){  /* modify counter here */ }

            while(/* counter condition */){ 
                 
                 /* update d here if finding minimum*/

                //increase begin to make it invalid/valid again
                
                if(map[s[begin++]]++ ?){ /*modify counter here*/ }
            }  

            /* update d here if finding maximum*/
        }
        return d;
  }

Key Concepts :

Similar to binary search. Try to find a condition that can make pointers keep moving to one direction until they meet in the middle (onward + backward) or meet at the end of the given array (sliding window)

Notation : Try not to use while loop because it is easy to write bugs.

Application :

  1. Find all results that satisfy some conditions in a given array
  2. Do particular permutation to a given array.

Extension : 3 pointers (Keep one pointer and do two pointer to the rest of the given array)

Common corner cases:

  1. end = s.length()

Greedy

Subsets

Sort(Divide Conquer in Array)

Binary Search

BFS

Application :

  1. Shortest path problem (especially for the case that each step counts 1, i.e. Matrix)
  2. Topological sorting
  3. Go through a graph
  4. Matrix problem

General Implementation Step:

  1. Traverse and collect all the start nodes and push them in a queue.
  2. Construct corresponding graph with given edges.
  3. while the queue becomes empty (Add extra Set if needed):
    • Poll one node from the queue each time and find its neighbors.
    • (if Set does not contains neighbors)Push the neighbors (in some conditions) into the queue.
  4. Return.

Binary Tree and Divide Conquer

General Implementation step:

  1. Set a global value if we need to find the max(min) value in Binary Tree.

  2. Set divide conquer rule :

    • What should we calculate for each node?
    • To achieve this, what value should we get from the return value of root.left and root.right?
    • How many possible cases root.left and root.right have (i.e. : common cases illustrated below)
    • What is the corresponding value for those cases? How to deal with those cases to write clearest code for if..else.. condition.
  3. Dealing with return statement like root == null

  4. Return result in main function

Common corner case:

  1. 4 cases when merging : root , root with left, root with right, root with left and right.

  2. root == null (especially, take extra care of the original root is null)

  3. leaf node can only be root.left == null && root.right == null

DFS

Dynamic Programming

Dynamic Programming is DFS/Divide Conquer + Memorization

General Implementation step:

  1. States:

    • The final state
    • The relation between final state and sub-states
  2. Transformation equation

  3. The first state and corner cases : ie. f[0] and f[< 0]

  4. The order of DP : Bottom-up or Up-bottom

Coordinates DP:

f[i] represents some property that end at ai

Common Corner cases: i == 0 || j == 0

Sequence DP:

f[i] represents some property of a0 to ai-1

Union Find

Template:

public class ConnectingGraph3 {
    int father[];
    int[] size;
    int count;

    public ConnectingGraph3(int n) {
        father = new int[n + 1];
        size = new int[n + 1];
        count = n;
        for (int i = 0; i <= n; i++) {
            father[i] = i;
            size[i] = 1;
        }
    }

    public void connect(int a, int b) {
        int fatherA = find(a);
        int fatherB = find(b);
        if (fatherA != fatherB) {
            father[fatherA] = fatherB;
            count--;
            size[fatherA] += size[fatherB];
        }
    }

    public int query(int a) {
        return count;//Or return size[find(a)];
    }
    
    public int find(int a) {
        if (father[a] == a) {
            return a;
        }
        
        return father[a] = find(father[a]);
    }
}

Common corner cases :

  1. We want to create or connect a node but the node is already created in the father array(has father already)
  2. We want to find a node but the node haven't created in the father array

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors